1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*
15  * Module Info: This module contains most of the "core" functionality of
16  *      the H5T interface, including the API initialization code, etc.
17  *      Many routines that are infrequently used, or are specialized for
18  *      one particular datatype class are in another module.
19  */
20 
21 /****************/
22 /* Module Setup */
23 /****************/
24 
25 #include "H5Tmodule.h"      /* This source code file is part of the H5T module */
26 
27 
28 /***********/
29 /* Headers */
30 /***********/
31 #include "H5private.h"      /* Generic Functions        */
32 #include "H5ACprivate.h"    /* Metadata cache           */
33 #include "H5CXprivate.h"    /* API Contexts             */
34 #include "H5Dprivate.h"     /* Datasets                 */
35 #include "H5Eprivate.h"     /* Error handling           */
36 #include "H5Fprivate.h"     /* Files                    */
37 #include "H5FLprivate.h"    /* Free Lists               */
38 #include "H5FOprivate.h"    /* File objects             */
39 #include "H5Gprivate.h"     /* Groups                   */
40 #include "H5Iprivate.h"     /* IDs                      */
41 #include "H5MMprivate.h"    /* Memory management        */
42 #include "H5Pprivate.h"     /* Property lists           */
43 #include "H5Tpkg.h"         /* Datatypes                */
44 
45 /* Check for header needed for SGI floating-point code */
46 #ifdef H5_HAVE_SYS_FPU_H
47 #include <sys/fpu.h>
48 #endif /* H5_HAVE_SYS_FPU_H */
49 
50 
51 /****************/
52 /* Local Macros */
53 /****************/
54 
55 #define H5T_ENCODE_VERSION      0
56 
57 /*
58  * Type initialization macros
59  *
60  * These use the "template macro" technique to reduce the amount of gratuitous
61  * duplicated code when initializing the datatypes for the library.  The main
62  * template macro is the H5T_INIT_TYPE() macro below.
63  *
64  */
65 
66 /* Define the code template for bitfields for the "GUTS" in the H5T_INIT_TYPE macro */
67 #define H5T_INIT_TYPE_BITFIELD_CORE {                       \
68     dt->shared->type = H5T_BITFIELD;                        \
69 }
70 
71 #define H5T_INIT_TYPE_BITFIELD_COMMON(ENDIANNESS) {            \
72     H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS)                       \
73     H5T_INIT_TYPE_BITFIELD_CORE;                               \
74 }
75 
76 #define H5T_INIT_TYPE_BITFIELDLE_CORE {                        \
77     H5T_INIT_TYPE_BITFIELD_COMMON(H5T_ORDER_LE)                \
78 }
79 
80 #define H5T_INIT_TYPE_BITFIELDBE_CORE {                        \
81     H5T_INIT_TYPE_BITFIELD_COMMON(H5T_ORDER_BE)                \
82 }
83 
84 /* Define the code template for times for the "GUTS" in the H5T_INIT_TYPE macro */
85 #define H5T_INIT_TYPE_TIME_CORE {                           \
86     dt->shared->type = H5T_TIME;                            \
87 }
88 
89 /* Define the code template for types which reset the offset for the "GUTS" in the H5T_INIT_TYPE macro */
90 #define H5T_INIT_TYPE_OFFSET_CORE {                         \
91     dt->shared->u.atomic.offset = 0;                        \
92 }
93 
94 /* Define common code for all numeric types (floating-point & int, signed & unsigned) */
95 #define H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS) {              \
96     dt->shared->u.atomic.order = ENDIANNESS;                \
97     dt->shared->u.atomic.offset = 0;                        \
98     dt->shared->u.atomic.lsb_pad = H5T_PAD_ZERO;            \
99     dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO;            \
100 }
101 
102 /* Define the code templates for standard floats for the "GUTS" in the H5T_INIT_TYPE macro */
103 #define H5T_INIT_TYPE_FLOAT_COMMON(ENDIANNESS) {            \
104     H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS)                    \
105     dt->shared->u.atomic.u.f.sign = 31;                     \
106     dt->shared->u.atomic.u.f.epos = 23;                     \
107     dt->shared->u.atomic.u.f.esize = 8;                     \
108     dt->shared->u.atomic.u.f.ebias = 0x7f;                  \
109     dt->shared->u.atomic.u.f.mpos = 0;                      \
110     dt->shared->u.atomic.u.f.msize = 23;                    \
111     dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED;       \
112     dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;            \
113 }
114 
115 #define H5T_INIT_TYPE_FLOATLE_CORE {                        \
116     H5T_INIT_TYPE_FLOAT_COMMON(H5T_ORDER_LE)                \
117 }
118 
119 #define H5T_INIT_TYPE_FLOATBE_CORE {                        \
120     H5T_INIT_TYPE_FLOAT_COMMON(H5T_ORDER_BE)                \
121 }
122 
123 /* Define the code templates for standard doubles for the "GUTS" in the H5T_INIT_TYPE macro */
124 #define H5T_INIT_TYPE_DOUBLE_COMMON(ENDIANNESS) {           \
125     H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS)                    \
126     dt->shared->u.atomic.u.f.sign = 63;                     \
127     dt->shared->u.atomic.u.f.epos = 52;                     \
128     dt->shared->u.atomic.u.f.esize = 11;                    \
129     dt->shared->u.atomic.u.f.ebias = 0x03ff;                \
130     dt->shared->u.atomic.u.f.mpos = 0;                      \
131     dt->shared->u.atomic.u.f.msize = 52;                    \
132     dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED;       \
133     dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;            \
134 }
135 
136 #define H5T_INIT_TYPE_DOUBLELE_CORE {                       \
137     H5T_INIT_TYPE_DOUBLE_COMMON(H5T_ORDER_LE)               \
138 }
139 
140 #define H5T_INIT_TYPE_DOUBLEBE_CORE {                       \
141     H5T_INIT_TYPE_DOUBLE_COMMON(H5T_ORDER_BE)               \
142 }
143 
144 /* Define the code templates for VAX float for the "GUTS" in the H5T_INIT_TYPE macro */
145 #define H5T_INIT_TYPE_FLOATVAX_CORE {                       \
146     H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_VAX)                 \
147     dt->shared->u.atomic.u.f.sign = 31;                     \
148     dt->shared->u.atomic.u.f.epos = 23;                     \
149     dt->shared->u.atomic.u.f.esize = 8;                     \
150     dt->shared->u.atomic.u.f.ebias = 0x81;                  \
151     dt->shared->u.atomic.u.f.mpos = 0;                      \
152     dt->shared->u.atomic.u.f.msize = 23;                    \
153     dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED;       \
154     dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;            \
155     dt->shared->version = H5O_DTYPE_VERSION_3;              \
156 }
157 
158 /* Define the code templates for VAX double for the "GUTS" in the H5T_INIT_TYPE macro */
159 #define H5T_INIT_TYPE_DOUBLEVAX_CORE {                      \
160     H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_VAX)                 \
161     dt->shared->u.atomic.u.f.sign = 63;                     \
162     dt->shared->u.atomic.u.f.epos = 52;                     \
163     dt->shared->u.atomic.u.f.esize = 11;                    \
164     dt->shared->u.atomic.u.f.ebias = 0x0401;                \
165     dt->shared->u.atomic.u.f.mpos = 0;                      \
166     dt->shared->u.atomic.u.f.msize = 52;                    \
167     dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED;       \
168     dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;            \
169     dt->shared->version = H5O_DTYPE_VERSION_3;              \
170 }
171 
172 /* Define the code templates for standard signed integers for the "GUTS" in the H5T_INIT_TYPE macro */
173 #define H5T_INIT_TYPE_SINT_COMMON(ENDIANNESS) {             \
174     H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS)                    \
175     dt->shared->u.atomic.u.i.sign = H5T_SGN_2;              \
176 }
177 
178 #define H5T_INIT_TYPE_SINTLE_CORE {                         \
179     H5T_INIT_TYPE_SINT_COMMON(H5T_ORDER_LE)                 \
180 }
181 
182 #define H5T_INIT_TYPE_SINTBE_CORE {                         \
183     H5T_INIT_TYPE_SINT_COMMON(H5T_ORDER_BE)                 \
184 }
185 
186 /* Define the code templates for standard unsigned integers for the "GUTS" in the H5T_INIT_TYPE macro */
187 #define H5T_INIT_TYPE_UINT_COMMON(ENDIANNESS) {             \
188     H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS)                    \
189     dt->shared->u.atomic.u.i.sign = H5T_SGN_NONE;           \
190 }
191 
192 #define H5T_INIT_TYPE_UINTLE_CORE {                         \
193     H5T_INIT_TYPE_UINT_COMMON(H5T_ORDER_LE)                 \
194 }
195 
196 #define H5T_INIT_TYPE_UINTBE_CORE {                         \
197     H5T_INIT_TYPE_UINT_COMMON(H5T_ORDER_BE)                 \
198 }
199 
200 /* Define a macro for common code for all newly allocate datatypes */
201 #define H5T_INIT_TYPE_ALLOC_COMMON(TYPE) {                  \
202     dt->sh_loc.type = H5O_SHARE_TYPE_UNSHARED;              \
203     dt->shared->type = TYPE;                                \
204 }
205 
206 /* Define the code templates for opaque for the "GUTS" in the H5T_INIT_TYPE macro */
207 #define H5T_INIT_TYPE_OPAQ_CORE {                           \
208     H5T_INIT_TYPE_ALLOC_COMMON(H5T_OPAQUE)                  \
209     dt->shared->u.opaque.tag = H5MM_xstrdup("");            \
210 }
211 
212 /* Define the code templates for strings for the "GUTS" in the H5T_INIT_TYPE macro */
213 #define H5T_INIT_TYPE_STRING_COMMON {                       \
214     H5T_INIT_TYPE_ALLOC_COMMON(H5T_STRING)                  \
215     H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_NONE)                \
216     dt->shared->u.atomic.u.s.cset = H5F_DEFAULT_CSET;       \
217 }
218 
219 #define H5T_INIT_TYPE_CSTRING_CORE {                        \
220     H5T_INIT_TYPE_STRING_COMMON                             \
221     dt->shared->u.atomic.u.s.pad = H5T_STR_NULLTERM;        \
222 }
223 
224 #define H5T_INIT_TYPE_FORSTRING_CORE {                      \
225     H5T_INIT_TYPE_STRING_COMMON                             \
226     dt->shared->u.atomic.u.s.pad = H5T_STR_SPACEPAD;        \
227 }
228 
229 /* Define the code templates for references for the "GUTS" in the H5T_INIT_TYPE macro */
230 #define H5T_INIT_TYPE_REF_COMMON {                          \
231     H5T_INIT_TYPE_ALLOC_COMMON(H5T_REFERENCE)               \
232     H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_NONE)                \
233 }
234 
235 #define H5T_INIT_TYPE_OBJREF_CORE {                         \
236     H5T_INIT_TYPE_REF_COMMON                                \
237     dt->shared->force_conv = TRUE;                          \
238     dt->shared->u.atomic.u.r.rtype = H5R_OBJECT;            \
239     dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY;          \
240 }
241 
242 #define H5T_INIT_TYPE_REGREF_CORE {                         \
243     H5T_INIT_TYPE_REF_COMMON                                \
244     dt->shared->u.atomic.u.r.rtype = H5R_DATASET_REGION;    \
245 }
246 
247 /* Define the code templates for the "SIZE_TMPL" in the H5T_INIT_TYPE macro */
248 #define H5T_INIT_TYPE_SET_SIZE(SIZE) {                      \
249     dt->shared->size = SIZE;                                \
250     dt->shared->u.atomic.prec = 8 * SIZE;                   \
251 }
252 
253 #define H5T_INIT_TYPE_NOSET_SIZE(SIZE) {                    \
254 }
255 
256 /* Define the code templates for the "CRT_TMPL" in the H5T_INIT_TYPE macro */
257 #define H5T_INIT_TYPE_COPY_CREATE(BASE) {                   \
258     /* Base off of existing datatype */                     \
259     if(NULL == (dt = H5T_copy(BASE, H5T_COPY_TRANSIENT)))   \
260         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "duplicating base type failed") \
261 }
262 
263 #define H5T_INIT_TYPE_ALLOC_CREATE(BASE) {                  \
264     /* Allocate new datatype info */                        \
265     if(NULL == (dt = H5T__alloc()))                         \
266         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed") \
267 }
268 
269 
270 #define H5T_INIT_TYPE(GUTS,GLOBAL,CRT_TMPL,BASE,SIZE_TMPL,SIZE) { \
271     /* Get new datatype struct */                           \
272     H5_GLUE3(H5T_INIT_TYPE_,CRT_TMPL,_CREATE)(BASE)         \
273                                                             \
274     /* Adjust information for all types */                  \
275     dt->shared->state = H5T_STATE_IMMUTABLE;                \
276     H5_GLUE3(H5T_INIT_TYPE_,SIZE_TMPL,_SIZE)(SIZE)          \
277                                                             \
278     /* Adjust information for this type */                  \
279     H5_GLUE3(H5T_INIT_TYPE_, GUTS, _CORE)                   \
280                                                             \
281     /* Atomize result */                                    \
282     if((GLOBAL = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)  \
283         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom") \
284 }
285 
286 
287 /******************/
288 /* Local Typedefs */
289 /******************/
290 
291 
292 /********************/
293 /* Local Prototypes */
294 /********************/
295 static herr_t H5T__register_int(H5T_pers_t pers, const char *name, H5T_t *src,
296     H5T_t *dst, H5T_lib_conv_t func);
297 static herr_t H5T__register(H5T_pers_t pers, const char *name, H5T_t *src,
298     H5T_t *dst, H5T_conv_func_t *conv);
299 static herr_t H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src,
300     H5T_t *dst, H5T_conv_t func);
301 static htri_t H5T__compiler_conv(H5T_t *src, H5T_t *dst);
302 static herr_t H5T__set_size(H5T_t *dt, size_t size);
303 static herr_t H5T__close_cb(H5T_t *dt);
304 static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst,
305     const char *name, H5T_conv_func_t *conv);
306 
307 
308 /*****************************/
309 /* Library Private Variables */
310 /*****************************/
311 
312 /* The native endianness of the platform */
313 H5T_order_t H5T_native_order_g = H5T_ORDER_ERROR;
314 
315 
316 /*********************/
317 /* Package Variables */
318 /*********************/
319 
320 /* Package initialization variable */
321 hbool_t H5_PKG_INIT_VAR = FALSE;
322 
323 /*
324  * Predefined data types. These are initialized at runtime in H5Tinit.c and
325  * by H5T__init_package() in this source file.
326  *
327  * If more of these are added, the new ones must be added to the list of
328  * types to reset in H5T_term_package().
329  */
330 hid_t H5T_IEEE_F32BE_g          = FAIL;
331 hid_t H5T_IEEE_F32LE_g          = FAIL;
332 hid_t H5T_IEEE_F64BE_g          = FAIL;
333 hid_t H5T_IEEE_F64LE_g          = FAIL;
334 
335 hid_t H5T_VAX_F32_g             = FAIL;
336 hid_t H5T_VAX_F64_g             = FAIL;
337 
338 hid_t H5T_STD_I8BE_g            = FAIL;
339 hid_t H5T_STD_I8LE_g            = FAIL;
340 hid_t H5T_STD_I16BE_g           = FAIL;
341 hid_t H5T_STD_I16LE_g           = FAIL;
342 hid_t H5T_STD_I32BE_g           = FAIL;
343 hid_t H5T_STD_I32LE_g           = FAIL;
344 hid_t H5T_STD_I64BE_g           = FAIL;
345 hid_t H5T_STD_I64LE_g           = FAIL;
346 hid_t H5T_STD_U8BE_g            = FAIL;
347 hid_t H5T_STD_U8LE_g            = FAIL;
348 hid_t H5T_STD_U16BE_g           = FAIL;
349 hid_t H5T_STD_U16LE_g           = FAIL;
350 hid_t H5T_STD_U32BE_g           = FAIL;
351 hid_t H5T_STD_U32LE_g           = FAIL;
352 hid_t H5T_STD_U64BE_g           = FAIL;
353 hid_t H5T_STD_U64LE_g           = FAIL;
354 hid_t H5T_STD_B8BE_g            = FAIL;
355 hid_t H5T_STD_B8LE_g            = FAIL;
356 hid_t H5T_STD_B16BE_g           = FAIL;
357 hid_t H5T_STD_B16LE_g           = FAIL;
358 hid_t H5T_STD_B32BE_g           = FAIL;
359 hid_t H5T_STD_B32LE_g           = FAIL;
360 hid_t H5T_STD_B64BE_g           = FAIL;
361 hid_t H5T_STD_B64LE_g           = FAIL;
362 hid_t H5T_STD_REF_OBJ_g         = FAIL;
363 hid_t H5T_STD_REF_DSETREG_g     = FAIL;
364 
365 hid_t H5T_UNIX_D32BE_g          = FAIL;
366 hid_t H5T_UNIX_D32LE_g          = FAIL;
367 hid_t H5T_UNIX_D64BE_g          = FAIL;
368 hid_t H5T_UNIX_D64LE_g          = FAIL;
369 
370 hid_t H5T_C_S1_g                = FAIL;
371 
372 hid_t H5T_FORTRAN_S1_g          = FAIL;
373 
374 hid_t H5T_NATIVE_SCHAR_g        = FAIL;
375 hid_t H5T_NATIVE_UCHAR_g        = FAIL;
376 hid_t H5T_NATIVE_SHORT_g        = FAIL;
377 hid_t H5T_NATIVE_USHORT_g       = FAIL;
378 hid_t H5T_NATIVE_INT_g          = FAIL;
379 hid_t H5T_NATIVE_UINT_g         = FAIL;
380 hid_t H5T_NATIVE_LONG_g         = FAIL;
381 hid_t H5T_NATIVE_ULONG_g        = FAIL;
382 hid_t H5T_NATIVE_LLONG_g        = FAIL;
383 hid_t H5T_NATIVE_ULLONG_g       = FAIL;
384 hid_t H5T_NATIVE_FLOAT_g        = FAIL;
385 hid_t H5T_NATIVE_DOUBLE_g       = FAIL;
386 #if H5_SIZEOF_LONG_DOUBLE !=0
387 hid_t H5T_NATIVE_LDOUBLE_g      = FAIL;
388 #endif
389 hid_t H5T_NATIVE_B8_g           = FAIL;
390 hid_t H5T_NATIVE_B16_g          = FAIL;
391 hid_t H5T_NATIVE_B32_g          = FAIL;
392 hid_t H5T_NATIVE_B64_g          = FAIL;
393 hid_t H5T_NATIVE_OPAQUE_g       = FAIL;
394 hid_t H5T_NATIVE_HADDR_g        = FAIL;
395 hid_t H5T_NATIVE_HSIZE_g        = FAIL;
396 hid_t H5T_NATIVE_HSSIZE_g       = FAIL;
397 hid_t H5T_NATIVE_HERR_g         = FAIL;
398 hid_t H5T_NATIVE_HBOOL_g        = FAIL;
399 
400 hid_t H5T_NATIVE_INT8_g         = FAIL;
401 hid_t H5T_NATIVE_UINT8_g        = FAIL;
402 hid_t H5T_NATIVE_INT_LEAST8_g   = FAIL;
403 hid_t H5T_NATIVE_UINT_LEAST8_g  = FAIL;
404 hid_t H5T_NATIVE_INT_FAST8_g    = FAIL;
405 hid_t H5T_NATIVE_UINT_FAST8_g   = FAIL;
406 
407 hid_t H5T_NATIVE_INT16_g        = FAIL;
408 hid_t H5T_NATIVE_UINT16_g       = FAIL;
409 hid_t H5T_NATIVE_INT_LEAST16_g  = FAIL;
410 hid_t H5T_NATIVE_UINT_LEAST16_g = FAIL;
411 hid_t H5T_NATIVE_INT_FAST16_g   = FAIL;
412 hid_t H5T_NATIVE_UINT_FAST16_g  = FAIL;
413 
414 hid_t H5T_NATIVE_INT32_g        = FAIL;
415 hid_t H5T_NATIVE_UINT32_g       = FAIL;
416 hid_t H5T_NATIVE_INT_LEAST32_g  = FAIL;
417 hid_t H5T_NATIVE_UINT_LEAST32_g = FAIL;
418 hid_t H5T_NATIVE_INT_FAST32_g   = FAIL;
419 hid_t H5T_NATIVE_UINT_FAST32_g  = FAIL;
420 
421 hid_t H5T_NATIVE_INT64_g        = FAIL;
422 hid_t H5T_NATIVE_UINT64_g       = FAIL;
423 hid_t H5T_NATIVE_INT_LEAST64_g  = FAIL;
424 hid_t H5T_NATIVE_UINT_LEAST64_g = FAIL;
425 hid_t H5T_NATIVE_INT_FAST64_g   = FAIL;
426 hid_t H5T_NATIVE_UINT_FAST64_g  = FAIL;
427 
428 /*
429  * Alignment constraints for native types. These are initialized at run time
430  * in H5Tinit.c.  These alignments are mainly for offsets in HDF5 compound
431  * datatype or C structures, which are different from the alignments for memory
432  * address below this group of variables.
433  */
434 size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g        = 0;
435 size_t H5T_NATIVE_UCHAR_COMP_ALIGN_g        = 0;
436 size_t H5T_NATIVE_SHORT_COMP_ALIGN_g        = 0;
437 size_t H5T_NATIVE_USHORT_COMP_ALIGN_g       = 0;
438 size_t H5T_NATIVE_INT_COMP_ALIGN_g          = 0;
439 size_t H5T_NATIVE_UINT_COMP_ALIGN_g         = 0;
440 size_t H5T_NATIVE_LONG_COMP_ALIGN_g         = 0;
441 size_t H5T_NATIVE_ULONG_COMP_ALIGN_g        = 0;
442 size_t H5T_NATIVE_LLONG_COMP_ALIGN_g        = 0;
443 size_t H5T_NATIVE_ULLONG_COMP_ALIGN_g       = 0;
444 size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g        = 0;
445 size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g       = 0;
446 #if H5_SIZEOF_LONG_DOUBLE !=0
447 size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g      = 0;
448 #endif
449 
450 size_t H5T_POINTER_COMP_ALIGN_g             = 0;
451 size_t H5T_HVL_COMP_ALIGN_g                 = 0;
452 size_t H5T_HOBJREF_COMP_ALIGN_g             = 0;
453 size_t H5T_HDSETREGREF_COMP_ALIGN_g         = 0;
454 
455 /*
456  * Alignment constraints for native types. These are initialized at run time
457  * in H5Tinit.c
458  */
459 size_t H5T_NATIVE_SCHAR_ALIGN_g             = 0;
460 size_t H5T_NATIVE_UCHAR_ALIGN_g             = 0;
461 size_t H5T_NATIVE_SHORT_ALIGN_g             = 0;
462 size_t H5T_NATIVE_USHORT_ALIGN_g            = 0;
463 size_t H5T_NATIVE_INT_ALIGN_g               = 0;
464 size_t H5T_NATIVE_UINT_ALIGN_g              = 0;
465 size_t H5T_NATIVE_LONG_ALIGN_g              = 0;
466 size_t H5T_NATIVE_ULONG_ALIGN_g             = 0;
467 size_t H5T_NATIVE_LLONG_ALIGN_g             = 0;
468 size_t H5T_NATIVE_ULLONG_ALIGN_g            = 0;
469 size_t H5T_NATIVE_FLOAT_ALIGN_g             = 0;
470 size_t H5T_NATIVE_DOUBLE_ALIGN_g            = 0;
471 #if H5_SIZEOF_LONG_DOUBLE !=0
472 size_t H5T_NATIVE_LDOUBLE_ALIGN_g           = 0;
473 #endif
474 
475 /*
476  * Alignment constraints for C9x types. These are initialized at run time in
477  * H5Tinit.c if the types are provided by the system. Otherwise we set their
478  * values to 0 here (no alignment calculated).
479  */
480 size_t H5T_NATIVE_INT8_ALIGN_g              = 0;
481 size_t H5T_NATIVE_UINT8_ALIGN_g             = 0;
482 size_t H5T_NATIVE_INT_LEAST8_ALIGN_g        = 0;
483 size_t H5T_NATIVE_UINT_LEAST8_ALIGN_g       = 0;
484 size_t H5T_NATIVE_INT_FAST8_ALIGN_g         = 0;
485 size_t H5T_NATIVE_UINT_FAST8_ALIGN_g        = 0;
486 
487 size_t H5T_NATIVE_INT16_ALIGN_g             = 0;
488 size_t H5T_NATIVE_UINT16_ALIGN_g            = 0;
489 size_t H5T_NATIVE_INT_LEAST16_ALIGN_g       = 0;
490 size_t H5T_NATIVE_UINT_LEAST16_ALIGN_g      = 0;
491 size_t H5T_NATIVE_INT_FAST16_ALIGN_g        = 0;
492 size_t H5T_NATIVE_UINT_FAST16_ALIGN_g       = 0;
493 
494 size_t H5T_NATIVE_INT32_ALIGN_g             = 0;
495 size_t H5T_NATIVE_UINT32_ALIGN_g            = 0;
496 size_t H5T_NATIVE_INT_LEAST32_ALIGN_g       = 0;
497 size_t H5T_NATIVE_UINT_LEAST32_ALIGN_g      = 0;
498 size_t H5T_NATIVE_INT_FAST32_ALIGN_g        = 0;
499 size_t H5T_NATIVE_UINT_FAST32_ALIGN_g       = 0;
500 
501 size_t H5T_NATIVE_INT64_ALIGN_g             = 0;
502 size_t H5T_NATIVE_UINT64_ALIGN_g            = 0;
503 size_t H5T_NATIVE_INT_LEAST64_ALIGN_g       = 0;
504 size_t H5T_NATIVE_UINT_LEAST64_ALIGN_g      = 0;
505 size_t H5T_NATIVE_INT_FAST64_ALIGN_g        = 0;
506 size_t H5T_NATIVE_UINT_FAST64_ALIGN_g       = 0;
507 
508 /* Useful floating-point values for conversion routines */
509 /* (+/- Inf for all floating-point types) */
510 float H5T_NATIVE_FLOAT_POS_INF_g            = 0.0f;
511 float H5T_NATIVE_FLOAT_NEG_INF_g            = 0.0f;
512 double H5T_NATIVE_DOUBLE_POS_INF_g          = (double)0.0f;
513 double H5T_NATIVE_DOUBLE_NEG_INF_g          = (double)0.0f;
514 
515 /* Declare the free list for H5T_t's and H5T_shared_t's */
516 H5FL_DEFINE(H5T_t);
517 H5FL_DEFINE(H5T_shared_t);
518 
519 /* Format version bounds for datatype */
520 const unsigned H5O_dtype_ver_bounds[] = {
521     H5O_DTYPE_VERSION_1,        /* H5F_LIBVER_EARLIEST */
522     H5O_DTYPE_VERSION_3,        /* H5F_LIBVER_V18 */
523     H5O_DTYPE_VERSION_LATEST    /* H5F_LIBVER_LATEST */
524 };
525 
526 /*******************/
527 /* Local Variables */
528 /*******************/
529 
530 /*
531  * The path database. Each path has a source and destination data type pair
532  * which is used as the key by which the `entries' array is sorted.
533  */
534 static struct {
535     int            npaths;        /*number of paths defined               */
536     size_t         apaths;        /*number of paths allocated             */
537     H5T_path_t   **path;          /*sorted array of path pointers         */
538     int            nsoft;         /*number of soft conversions defined    */
539     size_t         asoft;         /*number of soft conversions allocated  */
540     H5T_soft_t    *soft;          /*unsorted array of soft conversions    */
541 } H5T_g;
542 
543 /* Declare the free list for H5T_path_t's */
544 H5FL_DEFINE_STATIC(H5T_path_t);
545 
546 /* Datatype ID class */
547 static const H5I_class_t H5I_DATATYPE_CLS[1] = {{
548     H5I_DATATYPE,               /* ID class value */
549     0,                          /* Class flags    */
550     8,                          /* # of reserved IDs for class */
551     (H5I_free_t)H5T__close_cb   /* Callback routine for closing objects of this class */
552 }};
553 
554 
555 /* Flag indicating "top" of interface has been initialized */
556 static hbool_t H5T_top_package_initialize_s = FALSE;
557 
558 
559 
560 /*-------------------------------------------------------------------------
561  * Function:    H5T_init
562  *
563  * Purpose:    Initialize the interface from some other package.
564  *
565  * Return:    Success:    non-negative
566  *            Failure:    negative
567  *
568  * Programmer:    Robb Matzke
569  *              Wednesday, December 16, 1998
570  *
571  *-------------------------------------------------------------------------
572  */
573 herr_t
H5T_init(void)574 H5T_init(void)
575 {
576     herr_t ret_value = SUCCEED;   /* Return value */
577 
578     FUNC_ENTER_NOAPI(FAIL)
579     /* FUNC_ENTER() does all the work */
580 
581 done:
582     FUNC_LEAVE_NOAPI(ret_value)
583 } /* end H5T_init() */
584 
585 
586 /*-------------------------------------------------------------------------
587  * Function:    H5T__init_inf
588  *
589  * Purpose:    Initialize the +/- Infinity floating-poing values for type
590  *              conversion.
591  *
592  * Return:    Success:    non-negative
593  *            Failure:    negative
594  *
595  * Programmer:    Quincey Koziol
596  *              Saturday, November 22, 2003
597  *
598  *-------------------------------------------------------------------------
599  */
600 static herr_t
H5T__init_inf(void)601 H5T__init_inf(void)
602 {
603     H5T_t        *dst_p;        /* Datatype type operate on */
604     H5T_atomic_t *dst;          /* Datatype's atomic info   */
605     uint8_t      *d;            /* Pointer to value to set  */
606     size_t        half_size;    /* Half the type size       */
607     size_t        u;            /* Local index value        */
608     herr_t ret_value = SUCCEED; /* Return value             */
609 
610     FUNC_ENTER_STATIC
611 
612     /* Get the float datatype */
613     if(NULL == (dst_p = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g)))
614         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
615     dst = &dst_p->shared->u.atomic;
616 
617     /* Check that we can re-order the bytes correctly */
618     if(H5T_ORDER_LE != H5T_native_order_g && H5T_ORDER_BE != H5T_native_order_g)
619         HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order")
620 
621     /* +Inf */
622     d = (uint8_t *)&H5T_NATIVE_FLOAT_POS_INF_g;
623     H5T__bit_set(d, dst->u.f.sign, (size_t)1, FALSE);
624     H5T__bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
625     H5T__bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
626 
627     /* Swap the bytes if the machine architecture is big-endian */
628     if (H5T_ORDER_BE == H5T_native_order_g) {
629         half_size = dst_p->shared->size / 2;
630         for(u = 0; u < half_size; u++) {
631             uint8_t tmp = d[dst_p->shared->size - (u + 1)];
632             d[dst_p->shared->size - (u + 1)] = d[u];
633             d[u] = tmp;
634         } /* end for */
635     } /* end if */
636 
637     /* -Inf */
638     d = (uint8_t *)&H5T_NATIVE_FLOAT_NEG_INF_g;
639     H5T__bit_set(d, dst->u.f.sign, (size_t)1, TRUE);
640     H5T__bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
641     H5T__bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
642 
643     /* Swap the bytes if the machine architecture is big-endian */
644     if(H5T_ORDER_BE == H5T_native_order_g) {
645         half_size = dst_p->shared->size / 2;
646         for(u = 0; u < half_size; u++) {
647             uint8_t tmp = d[dst_p->shared->size - (u + 1)];
648             d[dst_p->shared->size - (u + 1)] = d[u];
649             d[u] = tmp;
650         } /* end for */
651     } /* end if */
652 
653     /* Get the double datatype */
654     if(NULL == (dst_p = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g)))
655         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
656     dst = &dst_p->shared->u.atomic;
657 
658     /* Check that we can re-order the bytes correctly */
659     if(H5T_ORDER_LE != H5T_native_order_g && H5T_ORDER_BE != H5T_native_order_g)
660         HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order")
661 
662     /* +Inf */
663     d = (uint8_t *)&H5T_NATIVE_DOUBLE_POS_INF_g;
664     H5T__bit_set(d, dst->u.f.sign, (size_t)1, FALSE);
665     H5T__bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
666     H5T__bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
667 
668     /* Swap the bytes if the machine architecture is big-endian */
669     if(H5T_ORDER_BE == H5T_native_order_g) {
670         half_size = dst_p->shared->size / 2;
671         for(u = 0; u < half_size; u++) {
672             uint8_t tmp = d[dst_p->shared->size - (u + 1)];
673             d[dst_p->shared->size - (u + 1)] = d[u];
674             d[u] = tmp;
675         } /* end for */
676     } /* end if */
677 
678     /* -Inf */
679     d = (uint8_t *)&H5T_NATIVE_DOUBLE_NEG_INF_g;
680     H5T__bit_set(d, dst->u.f.sign, (size_t)1, TRUE);
681     H5T__bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
682     H5T__bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
683 
684     /* Swap the bytes if the machine architecture is big-endian */
685     if(H5T_ORDER_BE == H5T_native_order_g) {
686         half_size = dst_p->shared->size / 2;
687         for(u = 0; u < half_size; u++) {
688             uint8_t tmp = d[dst_p->shared->size - (u + 1)];
689             d[dst_p->shared->size - (u + 1)] = d[u];
690             d[u] = tmp;
691         } /* end for */
692     } /* end if */
693 
694 done:
695     FUNC_LEAVE_NOAPI(ret_value)
696 } /* end H5T__init_inf() */
697 
698 
699 /*--------------------------------------------------------------------------
700 NAME
701    H5T__init_package -- Initialize interface-specific information
702 USAGE
703     herr__t H5T_init_package()
704 RETURNS
705     Non-negative on success/Negative on failure
706 DESCRIPTION
707     Initializes any interface-specific data or routines.
708 
709 --------------------------------------------------------------------------*/
710 herr_t
H5T__init_package(void)711 H5T__init_package(void)
712 {
713     H5T_t       *native_schar=NULL;     /* Datatype structure for native signed char */
714     H5T_t       *native_uchar=NULL;     /* Datatype structure for native unsigned char */
715     H5T_t       *native_short=NULL;     /* Datatype structure for native short */
716     H5T_t       *native_ushort=NULL;    /* Datatype structure for native unsigned short */
717     H5T_t       *native_int=NULL;       /* Datatype structure for native int */
718     H5T_t       *native_uint=NULL;      /* Datatype structure for native unsigned int */
719     H5T_t       *native_long=NULL;      /* Datatype structure for native long */
720     H5T_t       *native_ulong=NULL;     /* Datatype structure for native unsigned long */
721     H5T_t       *native_llong=NULL;     /* Datatype structure for native long long */
722     H5T_t       *native_ullong=NULL;    /* Datatype structure for native unsigned long long */
723     H5T_t       *native_float=NULL;     /* Datatype structure for native float */
724     H5T_t       *native_double=NULL;    /* Datatype structure for native double */
725 #if H5_SIZEOF_LONG_DOUBLE !=0
726     H5T_t       *native_ldouble=NULL;   /* Datatype structure for native long double */
727 #endif
728     H5T_t       *std_u8le=NULL;         /* Datatype structure for unsigned 8-bit little-endian integer */
729     H5T_t       *std_u8be=NULL;         /* Datatype structure for unsigned 8-bit big-endian integer */
730     H5T_t       *std_u16le=NULL;        /* Datatype structure for unsigned 16-bit little-endian integer */
731     H5T_t       *std_u16be=NULL;        /* Datatype structure for unsigned 16-bit big-endian integer */
732     H5T_t       *std_u32le=NULL;        /* Datatype structure for unsigned 32-bit little-endian integer */
733     H5T_t       *std_u32be=NULL;        /* Datatype structure for unsigned 32-bit big-endian integer */
734     H5T_t       *std_u64le=NULL;        /* Datatype structure for unsigned 64-bit little-endian integer */
735     H5T_t       *std_u64be=NULL;        /* Datatype structure for unsigned 64-bit big-endian integer */
736     H5T_t       *dt = NULL;
737     H5T_t       *fixedpt=NULL;          /* Datatype structure for native int */
738     H5T_t       *floatpt=NULL;          /* Datatype structure for native float */
739     H5T_t       *string=NULL;           /* Datatype structure for C string */
740     H5T_t       *bitfield=NULL;         /* Datatype structure for bitfield */
741     H5T_t       *compound=NULL;         /* Datatype structure for compound objects */
742     H5T_t       *enum_type=NULL;        /* Datatype structure for enum objects */
743     H5T_t       *vlen=NULL;             /* Datatype structure for vlen objects */
744     H5T_t       *array=NULL;            /* Datatype structure for array objects */
745     H5T_t       *objref=NULL;           /* Datatype structure for object reference objects */
746     hsize_t     dim[1]={1};             /* Dimension info for array datatype */
747     herr_t      status;
748     hbool_t     copied_dtype = TRUE;    /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
749     herr_t      ret_value = SUCCEED;    /* Return value */
750 
751     FUNC_ENTER_NOAPI_NOINIT
752 
753     /* Initialize the atom group for the file IDs */
754     if(H5I_register_type(H5I_DATATYPE_CLS) < 0)
755         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface")
756 
757     /* Make certain there aren't too many classes of datatypes defined */
758     /* Only 16 (numbered 0-15) are supported in the current file format */
759     HDcompile_assert(H5T_NCLASSES < 16);
760 
761     /*
762      * Initialize pre-defined native datatypes from code generated during
763      * the library configuration by H5detect.
764      */
765     if(H5T__init_native() < 0)
766         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface")
767 
768     /* Get the atomic datatype structures needed by the initialization code below */
769     if(NULL == (native_schar = (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g)))
770         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
771     if(NULL == (native_uchar = (H5T_t *)H5I_object(H5T_NATIVE_UCHAR_g)))
772         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
773     if(NULL == (native_short = (H5T_t *)H5I_object(H5T_NATIVE_SHORT_g)))
774         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
775     if(NULL == (native_ushort = (H5T_t *)H5I_object(H5T_NATIVE_USHORT_g)))
776         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
777     if(NULL == (native_int = (H5T_t *)H5I_object(H5T_NATIVE_INT_g)))
778         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
779     if(NULL == (native_uint = (H5T_t *)H5I_object(H5T_NATIVE_UINT_g)))
780         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
781     if(NULL == (native_long = (H5T_t *)H5I_object(H5T_NATIVE_LONG_g)))
782         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
783     if(NULL == (native_ulong = (H5T_t *)H5I_object(H5T_NATIVE_ULONG_g)))
784         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
785     if(NULL == (native_llong = (H5T_t *)H5I_object(H5T_NATIVE_LLONG_g)))
786         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
787     if(NULL == (native_ullong = (H5T_t *)H5I_object(H5T_NATIVE_ULLONG_g)))
788         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
789     if(NULL == (native_float = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g)))
790         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
791     if(NULL == (native_double = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g)))
792         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
793 #if H5_SIZEOF_LONG_DOUBLE !=0
794     if(NULL == (native_ldouble = (H5T_t *)H5I_object(H5T_NATIVE_LDOUBLE_g)))
795         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
796 #endif
797 
798     /*------------------------------------------------------------
799      * Derived native types
800      *------------------------------------------------------------
801      */
802 
803     /* 1-byte bit field */
804     H5T_INIT_TYPE(BITFIELD,H5T_NATIVE_B8_g,COPY,native_uint,SET,1)
805 
806     /* 2-byte bit field */
807     H5T_INIT_TYPE(BITFIELD,H5T_NATIVE_B16_g,COPY,native_uint,SET,2)
808 
809     /* 4-byte bit field */
810     H5T_INIT_TYPE(BITFIELD,H5T_NATIVE_B32_g,COPY,native_uint,SET,4)
811 
812     /* 8-byte bit field */
813     H5T_INIT_TYPE(BITFIELD,H5T_NATIVE_B64_g,COPY,native_uint,SET,8)
814 
815     /* haddr_t */
816     H5T_INIT_TYPE(OFFSET,H5T_NATIVE_HADDR_g,COPY,native_uint,SET,sizeof(haddr_t))
817 
818     /* hsize_t */
819     H5T_INIT_TYPE(OFFSET,H5T_NATIVE_HSIZE_g,COPY,native_uint,SET,sizeof(hsize_t))
820 
821     /* hssize_t */
822     H5T_INIT_TYPE(OFFSET,H5T_NATIVE_HSSIZE_g,COPY,native_int,SET,sizeof(hssize_t))
823 
824     /* herr_t */
825     H5T_INIT_TYPE(OFFSET,H5T_NATIVE_HERR_g,COPY,native_int,SET,sizeof(herr_t))
826 
827     /* hbool_t */
828     H5T_INIT_TYPE(OFFSET,H5T_NATIVE_HBOOL_g,COPY,native_uint,SET,sizeof(hbool_t))
829 
830     /*------------------------------------------------------------
831      * IEEE Types
832      *------------------------------------------------------------
833      */
834 
835     /* IEEE 4-byte little-endian float */
836     H5T_INIT_TYPE(FLOATLE,H5T_IEEE_F32LE_g,COPY,native_double,SET,4)
837 
838     /* IEEE 4-byte big-endian float */
839     H5T_INIT_TYPE(FLOATBE,H5T_IEEE_F32BE_g,COPY,native_double,SET,4)
840 
841     /* IEEE 8-byte little-endian float */
842     H5T_INIT_TYPE(DOUBLELE,H5T_IEEE_F64LE_g,COPY,native_double,SET,8)
843 
844     /* IEEE 8-byte big-endian float */
845     H5T_INIT_TYPE(DOUBLEBE,H5T_IEEE_F64BE_g,COPY,native_double,SET,8)
846 
847     /*------------------------------------------------------------
848      * VAX Types
849      *------------------------------------------------------------
850      */
851 
852     /* VAX 4-byte float */
853     H5T_INIT_TYPE(FLOATVAX,H5T_VAX_F32_g,COPY,native_double,SET,4)
854 
855     /* VAX 8-byte double */
856     H5T_INIT_TYPE(DOUBLEVAX,H5T_VAX_F64_g,COPY,native_double,SET,8)
857 
858     /*------------------------------------------------------------
859      * C99 types
860      *------------------------------------------------------------
861      */
862 
863     /* 1-byte little-endian (endianness is irrelevant) signed integer */
864     H5T_INIT_TYPE(SINTLE,H5T_STD_I8LE_g,COPY,native_int,SET,1)
865 
866     /* 1-byte big-endian (endianness is irrelevant) signed integer */
867     H5T_INIT_TYPE(SINTBE,H5T_STD_I8BE_g,COPY,native_int,SET,1)
868 
869     /* 2-byte little-endian signed integer */
870     H5T_INIT_TYPE(SINTLE,H5T_STD_I16LE_g,COPY,native_int,SET,2)
871 
872     /* 2-byte big-endian signed integer */
873     H5T_INIT_TYPE(SINTBE,H5T_STD_I16BE_g,COPY,native_int,SET,2)
874 
875     /* 4-byte little-endian signed integer */
876     H5T_INIT_TYPE(SINTLE,H5T_STD_I32LE_g,COPY,native_int,SET,4)
877 
878     /* 4-byte big-endian signed integer */
879     H5T_INIT_TYPE(SINTBE,H5T_STD_I32BE_g,COPY,native_int,SET,4)
880 
881     /* 8-byte little-endian signed integer */
882     H5T_INIT_TYPE(SINTLE,H5T_STD_I64LE_g,COPY,native_int,SET,8)
883 
884     /* 8-byte big-endian signed integer */
885     H5T_INIT_TYPE(SINTBE,H5T_STD_I64BE_g,COPY,native_int,SET,8)
886 
887     /* 1-byte little-endian (endianness is irrelevant) unsigned integer */
888     H5T_INIT_TYPE(UINTLE,H5T_STD_U8LE_g,COPY,native_uint,SET,1)
889     std_u8le=dt;    /* Keep type for later */
890 
891     /* 1-byte big-endian (endianness is irrelevant) unsigned integer */
892     H5T_INIT_TYPE(UINTBE,H5T_STD_U8BE_g,COPY,native_uint,SET,1)
893     std_u8be=dt;    /* Keep type for later */
894 
895     /* 2-byte little-endian unsigned integer */
896     H5T_INIT_TYPE(UINTLE,H5T_STD_U16LE_g,COPY,native_uint,SET,2)
897     std_u16le=dt;    /* Keep type for later */
898 
899     /* 2-byte big-endian unsigned integer */
900     H5T_INIT_TYPE(UINTBE,H5T_STD_U16BE_g,COPY,native_uint,SET,2)
901     std_u16be=dt;    /* Keep type for later */
902 
903     /* 4-byte little-endian unsigned integer */
904     H5T_INIT_TYPE(UINTLE,H5T_STD_U32LE_g,COPY,native_uint,SET,4)
905     std_u32le=dt;    /* Keep type for later */
906 
907     /* 4-byte big-endian unsigned integer */
908     H5T_INIT_TYPE(UINTBE,H5T_STD_U32BE_g,COPY,native_uint,SET,4)
909     std_u32be=dt;    /* Keep type for later */
910 
911     /* 8-byte little-endian unsigned integer */
912     H5T_INIT_TYPE(UINTLE,H5T_STD_U64LE_g,COPY,native_uint,SET,8)
913     std_u64le=dt;    /* Keep type for later */
914 
915     /* 8-byte big-endian unsigned integer */
916     H5T_INIT_TYPE(UINTBE,H5T_STD_U64BE_g,COPY,native_uint,SET,8)
917     std_u64be=dt;    /* Keep type for later */
918 
919     /*------------------------------------------------------------
920      * Native, Little- & Big-endian bitfields
921      *------------------------------------------------------------
922      */
923 
924     /* little-endian (order is irrelevant) 8-bit bitfield */
925     H5T_INIT_TYPE(BITFIELDLE, H5T_STD_B8LE_g, COPY, std_u8le, NOSET, -)
926     bitfield=dt;    /* Keep type for later */
927 
928     /* big-endian (order is irrelevant) 8-bit bitfield */
929     H5T_INIT_TYPE(BITFIELDBE, H5T_STD_B8BE_g, COPY, std_u8be, NOSET, -)
930 
931     /* Little-endian 16-bit bitfield */
932     H5T_INIT_TYPE(BITFIELDLE, H5T_STD_B16LE_g, COPY, std_u16le, NOSET, -)
933 
934     /* Big-endian 16-bit bitfield */
935     H5T_INIT_TYPE(BITFIELDBE, H5T_STD_B16BE_g, COPY, std_u16be, NOSET, -)
936 
937     /* Little-endian 32-bit bitfield */
938     H5T_INIT_TYPE(BITFIELDLE, H5T_STD_B32LE_g, COPY, std_u32le, NOSET, -)
939 
940     /* Big-endian 32-bit bitfield */
941     H5T_INIT_TYPE(BITFIELDBE, H5T_STD_B32BE_g, COPY, std_u32be, NOSET, -)
942 
943     /* Little-endian 64-bit bitfield */
944     H5T_INIT_TYPE(BITFIELDLE, H5T_STD_B64LE_g, COPY, std_u64le, NOSET, -)
945 
946     /* Big-endian 64-bit bitfield */
947     H5T_INIT_TYPE(BITFIELDBE, H5T_STD_B64BE_g, COPY, std_u64be, NOSET, -)
948 
949     /*------------------------------------------------------------
950      * The Unix architecture for dates and times.
951      *------------------------------------------------------------
952      */
953 
954     /* Little-endian 32-bit UNIX time_t */
955     H5T_INIT_TYPE(TIME, H5T_UNIX_D32LE_g, COPY, std_u32le, NOSET, -)
956 
957     /* Big-endian 32-bit UNIX time_t */
958     H5T_INIT_TYPE(TIME, H5T_UNIX_D32BE_g, COPY, std_u32be, NOSET, -)
959 
960     /* Little-endian 64-bit UNIX time_t */
961     H5T_INIT_TYPE(TIME, H5T_UNIX_D64LE_g, COPY, std_u64le, NOSET, -)
962 
963     /* Big-endian 64-bit UNIX time_t */
964     H5T_INIT_TYPE(TIME, H5T_UNIX_D64BE_g, COPY, std_u64be, NOSET, -)
965 
966 
967     /* Indicate that the types that are created from here down are allocated
968      * H5FL_ALLOC(), not copied with H5T_copy()
969      */
970     copied_dtype = FALSE;
971 
972     /* Opaque data */
973     H5T_INIT_TYPE(OPAQ, H5T_NATIVE_OPAQUE_g, ALLOC, -, SET, 1)
974 
975     /*------------------------------------------------------------
976      * The `C' architecture
977      *------------------------------------------------------------
978      */
979 
980     /* One-byte character string */
981     H5T_INIT_TYPE(CSTRING, H5T_C_S1_g, ALLOC, -, SET, 1)
982     string = dt;    /* Keep type for later */
983 
984     /*------------------------------------------------------------
985      * The `Fortran' architecture
986      *------------------------------------------------------------
987      */
988 
989     /* One-byte character string */
990     H5T_INIT_TYPE(FORSTRING, H5T_FORTRAN_S1_g, ALLOC, -, SET, 1)
991 
992     /*------------------------------------------------------------
993      * Reference types
994      *------------------------------------------------------------
995      */
996 
997     /* Object reference (i.e. object header address in file) */
998     H5T_INIT_TYPE(OBJREF, H5T_STD_REF_OBJ_g, ALLOC, -, SET, H5R_OBJ_REF_BUF_SIZE)
999     objref = dt;    /* Keep type for later */
1000 
1001     /* Dataset Region reference (i.e. selection inside a dataset) */
1002     H5T_INIT_TYPE(REGREF, H5T_STD_REF_DSETREG_g, ALLOC, -, SET, H5R_DSET_REG_REF_BUF_SIZE)
1003 
1004     /*
1005      * Register conversion functions beginning with the most general and
1006      * ending with the most specific.
1007      */
1008     fixedpt = native_int;
1009     floatpt = native_float;
1010     if (NULL == (compound = H5T__create(H5T_COMPOUND, (size_t)1)))
1011         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1012     if (NULL == (enum_type = H5T__create(H5T_ENUM, (size_t)1)))
1013         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1014     if (NULL == (vlen = H5T__vlen_create(native_int)))
1015         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1016     if (NULL == (array = H5T__array_create(native_int, 1, dim)))
1017         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1018     status = 0;
1019 
1020     status |= H5T__register_int(H5T_PERS_SOFT, "i_i", fixedpt, fixedpt, H5T__conv_i_i);
1021     status |= H5T__register_int(H5T_PERS_SOFT, "i_f", fixedpt, floatpt, H5T__conv_i_f);
1022     status |= H5T__register_int(H5T_PERS_SOFT, "f_f", floatpt, floatpt, H5T__conv_f_f);
1023     status |= H5T__register_int(H5T_PERS_SOFT, "f_i", floatpt, fixedpt, H5T__conv_f_i);
1024     status |= H5T__register_int(H5T_PERS_SOFT, "s_s", string, string, H5T__conv_s_s);
1025     status |= H5T__register_int(H5T_PERS_SOFT, "b_b", bitfield, bitfield, H5T__conv_b_b);
1026     status |= H5T__register_int(H5T_PERS_SOFT, "ibo", fixedpt, fixedpt, H5T__conv_order);
1027     status |= H5T__register_int(H5T_PERS_SOFT, "ibo(opt)", fixedpt, fixedpt, H5T__conv_order_opt);
1028     status |= H5T__register_int(H5T_PERS_SOFT, "fbo", floatpt, floatpt, H5T__conv_order);
1029     status |= H5T__register_int(H5T_PERS_SOFT, "fbo(opt)", floatpt, floatpt, H5T__conv_order_opt);
1030     status |= H5T__register_int(H5T_PERS_SOFT, "struct(no-opt)", compound, compound, H5T__conv_struct);
1031     status |= H5T__register_int(H5T_PERS_SOFT, "struct(opt)", compound, compound, H5T__conv_struct_opt);
1032     status |= H5T__register_int(H5T_PERS_SOFT, "enum", enum_type, enum_type, H5T__conv_enum);
1033     status |= H5T__register_int(H5T_PERS_SOFT, "enum_i", enum_type, fixedpt, H5T__conv_enum_numeric);
1034     status |= H5T__register_int(H5T_PERS_SOFT, "enum_f", enum_type, floatpt, H5T__conv_enum_numeric);
1035     status |= H5T__register_int(H5T_PERS_SOFT, "vlen", vlen, vlen, H5T__conv_vlen);
1036     status |= H5T__register_int(H5T_PERS_SOFT, "array", array, array, H5T__conv_array);
1037     status |= H5T__register_int(H5T_PERS_SOFT, "objref", objref, objref, H5T__conv_order_opt);
1038 
1039     /*
1040      * Native conversions should be listed last since we can use hardware to
1041      * perform the conversion.  We list the odd types like `llong', `long',
1042      * and `short' before the usual types like `int' and `char' so that when
1043      * diagnostics are printed we favor the usual names over the odd names
1044      * when two or more types are the same size.
1045      */
1046 
1047     /* floating point */
1048     status |= H5T__register_int(H5T_PERS_HARD, "flt_dbl", native_float, native_double, H5T__conv_float_double);
1049     status |= H5T__register_int(H5T_PERS_HARD, "dbl_flt", native_double, native_float, H5T__conv_double_float);
1050 #if H5_SIZEOF_LONG_DOUBLE != 0
1051     status |= H5T__register_int(H5T_PERS_HARD, "flt_ldbl", native_float, native_ldouble, H5T__conv_float_ldouble);
1052     status |= H5T__register_int(H5T_PERS_HARD, "dbl_ldbl", native_double, native_ldouble, H5T__conv_double_ldouble);
1053     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_flt", native_ldouble, native_float, H5T__conv_ldouble_float);
1054     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_dbl", native_ldouble, native_double, H5T__conv_ldouble_double);
1055 #endif /* H5_SIZEOF_LONG_DOUBLE != 0 */
1056 
1057     /* from long long */
1058     status |= H5T__register_int(H5T_PERS_HARD, "llong_ullong", native_llong, native_ullong, H5T__conv_llong_ullong);
1059     status |= H5T__register_int(H5T_PERS_HARD, "ullong_llong", native_ullong, native_llong, H5T__conv_ullong_llong);
1060     status |= H5T__register_int(H5T_PERS_HARD, "llong_long", native_llong, native_long, H5T__conv_llong_long);
1061     status |= H5T__register_int(H5T_PERS_HARD, "llong_ulong", native_llong, native_ulong, H5T__conv_llong_ulong);
1062     status |= H5T__register_int(H5T_PERS_HARD, "ullong_long", native_ullong, native_long, H5T__conv_ullong_long);
1063     status |= H5T__register_int(H5T_PERS_HARD, "ullong_ulong", native_ullong, native_ulong, H5T__conv_ullong_ulong);
1064     status |= H5T__register_int(H5T_PERS_HARD, "llong_short", native_llong, native_short, H5T__conv_llong_short);
1065     status |= H5T__register_int(H5T_PERS_HARD, "llong_ushort", native_llong, native_ushort, H5T__conv_llong_ushort);
1066     status |= H5T__register_int(H5T_PERS_HARD, "ullong_short", native_ullong, native_short, H5T__conv_ullong_short);
1067     status |= H5T__register_int(H5T_PERS_HARD, "ullong_ushort", native_ullong, native_ushort, H5T__conv_ullong_ushort);
1068     status |= H5T__register_int(H5T_PERS_HARD, "llong_int", native_llong, native_int, H5T__conv_llong_int);
1069     status |= H5T__register_int(H5T_PERS_HARD, "llong_uint", native_llong, native_uint, H5T__conv_llong_uint);
1070     status |= H5T__register_int(H5T_PERS_HARD, "ullong_int", native_ullong, native_int, H5T__conv_ullong_int);
1071     status |= H5T__register_int(H5T_PERS_HARD, "ullong_uint", native_ullong, native_uint, H5T__conv_ullong_uint);
1072     status |= H5T__register_int(H5T_PERS_HARD, "llong_schar", native_llong, native_schar, H5T__conv_llong_schar);
1073     status |= H5T__register_int(H5T_PERS_HARD, "llong_uchar", native_llong, native_uchar, H5T__conv_llong_uchar);
1074     status |= H5T__register_int(H5T_PERS_HARD, "ullong_schar", native_ullong, native_schar, H5T__conv_ullong_schar);
1075     status |= H5T__register_int(H5T_PERS_HARD, "ullong_uchar", native_ullong, native_uchar, H5T__conv_ullong_uchar);
1076 
1077     /* From long */
1078     status |= H5T__register_int(H5T_PERS_HARD, "long_llong", native_long, native_llong, H5T__conv_long_llong);
1079     status |= H5T__register_int(H5T_PERS_HARD, "long_ullong", native_long, native_ullong, H5T__conv_long_ullong);
1080     status |= H5T__register_int(H5T_PERS_HARD, "ulong_llong", native_ulong, native_llong, H5T__conv_ulong_llong);
1081     status |= H5T__register_int(H5T_PERS_HARD, "ulong_ullong", native_ulong, native_ullong, H5T__conv_ulong_ullong);
1082     status |= H5T__register_int(H5T_PERS_HARD, "long_ulong", native_long, native_ulong, H5T__conv_long_ulong);
1083     status |= H5T__register_int(H5T_PERS_HARD, "ulong_long", native_ulong, native_long, H5T__conv_ulong_long);
1084     status |= H5T__register_int(H5T_PERS_HARD, "long_short", native_long, native_short, H5T__conv_long_short);
1085     status |= H5T__register_int(H5T_PERS_HARD, "long_ushort", native_long, native_ushort, H5T__conv_long_ushort);
1086     status |= H5T__register_int(H5T_PERS_HARD, "ulong_short", native_ulong, native_short, H5T__conv_ulong_short);
1087     status |= H5T__register_int(H5T_PERS_HARD, "ulong_ushort", native_ulong, native_ushort, H5T__conv_ulong_ushort);
1088     status |= H5T__register_int(H5T_PERS_HARD, "long_int", native_long, native_int, H5T__conv_long_int);
1089     status |= H5T__register_int(H5T_PERS_HARD, "long_uint", native_long, native_uint, H5T__conv_long_uint);
1090     status |= H5T__register_int(H5T_PERS_HARD, "ulong_int", native_ulong, native_int, H5T__conv_ulong_int);
1091     status |= H5T__register_int(H5T_PERS_HARD, "ulong_uint", native_ulong, native_uint, H5T__conv_ulong_uint);
1092     status |= H5T__register_int(H5T_PERS_HARD, "long_schar", native_long, native_schar, H5T__conv_long_schar);
1093     status |= H5T__register_int(H5T_PERS_HARD, "long_uchar", native_long, native_uchar, H5T__conv_long_uchar);
1094     status |= H5T__register_int(H5T_PERS_HARD, "ulong_schar", native_ulong, native_schar, H5T__conv_ulong_schar);
1095     status |= H5T__register_int(H5T_PERS_HARD, "ulong_uchar", native_ulong, native_uchar, H5T__conv_ulong_uchar);
1096 
1097     /* From short */
1098     status |= H5T__register_int(H5T_PERS_HARD, "short_llong", native_short, native_llong, H5T__conv_short_llong);
1099     status |= H5T__register_int(H5T_PERS_HARD, "short_ullong", native_short, native_ullong, H5T__conv_short_ullong);
1100     status |= H5T__register_int(H5T_PERS_HARD, "ushort_llong", native_ushort, native_llong, H5T__conv_ushort_llong);
1101     status |= H5T__register_int(H5T_PERS_HARD, "ushort_ullong", native_ushort, native_ullong, H5T__conv_ushort_ullong);
1102     status |= H5T__register_int(H5T_PERS_HARD, "short_long", native_short, native_long, H5T__conv_short_long);
1103     status |= H5T__register_int(H5T_PERS_HARD, "short_ulong", native_short, native_ulong, H5T__conv_short_ulong);
1104     status |= H5T__register_int(H5T_PERS_HARD, "ushort_long", native_ushort, native_long, H5T__conv_ushort_long);
1105     status |= H5T__register_int(H5T_PERS_HARD, "ushort_ulong", native_ushort, native_ulong, H5T__conv_ushort_ulong);
1106     status |= H5T__register_int(H5T_PERS_HARD, "short_ushort", native_short, native_ushort, H5T__conv_short_ushort);
1107     status |= H5T__register_int(H5T_PERS_HARD, "ushort_short", native_ushort, native_short, H5T__conv_ushort_short);
1108     status |= H5T__register_int(H5T_PERS_HARD, "short_int", native_short, native_int, H5T__conv_short_int);
1109     status |= H5T__register_int(H5T_PERS_HARD, "short_uint", native_short, native_uint, H5T__conv_short_uint);
1110     status |= H5T__register_int(H5T_PERS_HARD, "ushort_int", native_ushort, native_int, H5T__conv_ushort_int);
1111     status |= H5T__register_int(H5T_PERS_HARD, "ushort_uint", native_ushort, native_uint, H5T__conv_ushort_uint);
1112     status |= H5T__register_int(H5T_PERS_HARD, "short_schar", native_short, native_schar, H5T__conv_short_schar);
1113     status |= H5T__register_int(H5T_PERS_HARD, "short_uchar", native_short, native_uchar, H5T__conv_short_uchar);
1114     status |= H5T__register_int(H5T_PERS_HARD, "ushort_schar", native_ushort, native_schar, H5T__conv_ushort_schar);
1115     status |= H5T__register_int(H5T_PERS_HARD, "ushort_uchar", native_ushort, native_uchar, H5T__conv_ushort_uchar);
1116 
1117     /* From int */
1118     status |= H5T__register_int(H5T_PERS_HARD, "int_llong", native_int, native_llong, H5T__conv_int_llong);
1119     status |= H5T__register_int(H5T_PERS_HARD, "int_ullong", native_int, native_ullong, H5T__conv_int_ullong);
1120     status |= H5T__register_int(H5T_PERS_HARD, "uint_llong", native_uint, native_llong, H5T__conv_uint_llong);
1121     status |= H5T__register_int(H5T_PERS_HARD, "uint_ullong", native_uint, native_ullong, H5T__conv_uint_ullong);
1122     status |= H5T__register_int(H5T_PERS_HARD, "int_long", native_int, native_long, H5T__conv_int_long);
1123     status |= H5T__register_int(H5T_PERS_HARD, "int_ulong", native_int, native_ulong, H5T__conv_int_ulong);
1124     status |= H5T__register_int(H5T_PERS_HARD, "uint_long", native_uint, native_long, H5T__conv_uint_long);
1125     status |= H5T__register_int(H5T_PERS_HARD, "uint_ulong", native_uint, native_ulong, H5T__conv_uint_ulong);
1126     status |= H5T__register_int(H5T_PERS_HARD, "int_short", native_int, native_short, H5T__conv_int_short);
1127     status |= H5T__register_int(H5T_PERS_HARD, "int_ushort", native_int, native_ushort, H5T__conv_int_ushort);
1128     status |= H5T__register_int(H5T_PERS_HARD, "uint_short", native_uint, native_short, H5T__conv_uint_short);
1129     status |= H5T__register_int(H5T_PERS_HARD, "uint_ushort", native_uint, native_ushort, H5T__conv_uint_ushort);
1130     status |= H5T__register_int(H5T_PERS_HARD, "int_uint", native_int, native_uint, H5T__conv_int_uint);
1131     status |= H5T__register_int(H5T_PERS_HARD, "uint_int", native_uint, native_int, H5T__conv_uint_int);
1132     status |= H5T__register_int(H5T_PERS_HARD, "int_schar", native_int, native_schar, H5T__conv_int_schar);
1133     status |= H5T__register_int(H5T_PERS_HARD, "int_uchar", native_int, native_uchar, H5T__conv_int_uchar);
1134     status |= H5T__register_int(H5T_PERS_HARD, "uint_schar", native_uint, native_schar, H5T__conv_uint_schar);
1135     status |= H5T__register_int(H5T_PERS_HARD, "uint_uchar", native_uint, native_uchar, H5T__conv_uint_uchar);
1136 
1137     /* From char */
1138     status |= H5T__register_int(H5T_PERS_HARD, "schar_llong", native_schar, native_llong, H5T__conv_schar_llong);
1139     status |= H5T__register_int(H5T_PERS_HARD, "schar_ullong", native_schar, native_ullong, H5T__conv_schar_ullong);
1140     status |= H5T__register_int(H5T_PERS_HARD, "uchar_llong", native_uchar, native_llong, H5T__conv_uchar_llong);
1141     status |= H5T__register_int(H5T_PERS_HARD, "uchar_ullong", native_uchar, native_ullong, H5T__conv_uchar_ullong);
1142     status |= H5T__register_int(H5T_PERS_HARD, "schar_long", native_schar, native_long, H5T__conv_schar_long);
1143     status |= H5T__register_int(H5T_PERS_HARD, "schar_ulong", native_schar, native_ulong, H5T__conv_schar_ulong);
1144     status |= H5T__register_int(H5T_PERS_HARD, "uchar_long", native_uchar, native_long, H5T__conv_uchar_long);
1145     status |= H5T__register_int(H5T_PERS_HARD, "uchar_ulong", native_uchar, native_ulong, H5T__conv_uchar_ulong);
1146     status |= H5T__register_int(H5T_PERS_HARD, "schar_short", native_schar, native_short, H5T__conv_schar_short);
1147     status |= H5T__register_int(H5T_PERS_HARD, "schar_ushort", native_schar, native_ushort, H5T__conv_schar_ushort);
1148     status |= H5T__register_int(H5T_PERS_HARD, "uchar_short", native_uchar, native_short, H5T__conv_uchar_short);
1149     status |= H5T__register_int(H5T_PERS_HARD, "uchar_ushort", native_uchar, native_ushort, H5T__conv_uchar_ushort);
1150     status |= H5T__register_int(H5T_PERS_HARD, "schar_int", native_schar, native_int, H5T__conv_schar_int);
1151     status |= H5T__register_int(H5T_PERS_HARD, "schar_uint", native_schar, native_uint, H5T__conv_schar_uint);
1152     status |= H5T__register_int(H5T_PERS_HARD, "uchar_int", native_uchar, native_int, H5T__conv_uchar_int);
1153     status |= H5T__register_int(H5T_PERS_HARD, "uchar_uint", native_uchar, native_uint, H5T__conv_uchar_uint);
1154     status |= H5T__register_int(H5T_PERS_HARD, "schar_uchar", native_schar, native_uchar, H5T__conv_schar_uchar);
1155     status |= H5T__register_int(H5T_PERS_HARD, "uchar_schar", native_uchar, native_schar, H5T__conv_uchar_schar);
1156 
1157     /* From char to floats */
1158     status |= H5T__register_int(H5T_PERS_HARD, "schar_flt", native_schar, native_float, H5T__conv_schar_float);
1159     status |= H5T__register_int(H5T_PERS_HARD, "schar_dbl", native_schar, native_double, H5T__conv_schar_double);
1160     status |= H5T__register_int(H5T_PERS_HARD, "schar_ldbl", native_schar, native_ldouble, H5T__conv_schar_ldouble);
1161 
1162     /* From unsigned char to floats */
1163     status |= H5T__register_int(H5T_PERS_HARD, "uchar_flt", native_uchar, native_float, H5T__conv_uchar_float);
1164     status |= H5T__register_int(H5T_PERS_HARD, "uchar_dbl", native_uchar, native_double, H5T__conv_uchar_double);
1165     status |= H5T__register_int(H5T_PERS_HARD, "uchar_ldbl", native_uchar, native_ldouble, H5T__conv_uchar_ldouble);
1166 
1167     /* From short to floats */
1168     status |= H5T__register_int(H5T_PERS_HARD, "short_flt", native_short, native_float, H5T__conv_short_float);
1169     status |= H5T__register_int(H5T_PERS_HARD, "short_dbl", native_short, native_double, H5T__conv_short_double);
1170     status |= H5T__register_int(H5T_PERS_HARD, "short_ldbl", native_short, native_ldouble, H5T__conv_short_ldouble);
1171 
1172     /* From unsigned short to floats */
1173     status |= H5T__register_int(H5T_PERS_HARD, "ushort_flt", native_ushort, native_float, H5T__conv_ushort_float);
1174     status |= H5T__register_int(H5T_PERS_HARD, "ushort_dbl", native_ushort, native_double, H5T__conv_ushort_double);
1175     status |= H5T__register_int(H5T_PERS_HARD, "ushort_ldbl", native_ushort, native_ldouble, H5T__conv_ushort_ldouble);
1176 
1177     /* From int to floats */
1178     status |= H5T__register_int(H5T_PERS_HARD, "int_flt", native_int, native_float, H5T__conv_int_float);
1179     status |= H5T__register_int(H5T_PERS_HARD, "int_dbl", native_int, native_double, H5T__conv_int_double);
1180     status |= H5T__register_int(H5T_PERS_HARD, "int_ldbl", native_int, native_ldouble, H5T__conv_int_ldouble);
1181 
1182     /* From unsigned int to floats */
1183     status |= H5T__register_int(H5T_PERS_HARD, "uint_flt", native_uint, native_float, H5T__conv_uint_float);
1184     status |= H5T__register_int(H5T_PERS_HARD, "uint_dbl", native_uint, native_double, H5T__conv_uint_double);
1185     status |= H5T__register_int(H5T_PERS_HARD, "uint_ldbl", native_uint, native_ldouble, H5T__conv_uint_ldouble);
1186 
1187     /* From long to floats */
1188     status |= H5T__register_int(H5T_PERS_HARD, "long_flt", native_long, native_float, H5T__conv_long_float);
1189     status |= H5T__register_int(H5T_PERS_HARD, "long_dbl", native_long, native_double, H5T__conv_long_double);
1190     status |= H5T__register_int(H5T_PERS_HARD, "long_ldbl", native_long, native_ldouble, H5T__conv_long_ldouble);
1191 
1192     /* From unsigned long to floats */
1193     status |= H5T__register_int(H5T_PERS_HARD, "ulong_flt", native_ulong, native_float, H5T__conv_ulong_float);
1194     status |= H5T__register_int(H5T_PERS_HARD, "ulong_dbl", native_ulong, native_double, H5T__conv_ulong_double);
1195     status |= H5T__register_int(H5T_PERS_HARD, "ulong_ldbl", native_ulong, native_ldouble, H5T__conv_ulong_ldouble);
1196 
1197     /* From long long to floats */
1198     status |= H5T__register_int(H5T_PERS_HARD, "llong_flt", native_llong, native_float, H5T__conv_llong_float);
1199     status |= H5T__register_int(H5T_PERS_HARD, "llong_dbl", native_llong, native_double, H5T__conv_llong_double);
1200 #ifdef H5T_CONV_INTERNAL_LLONG_LDOUBLE
1201     status |= H5T__register_int(H5T_PERS_HARD, "llong_ldbl", native_llong, native_ldouble, H5T__conv_llong_ldouble);
1202 #endif /* H5T_CONV_INTERNAL_LLONG_LDOUBLE */
1203 
1204     /* From unsigned long long to floats */
1205     status |= H5T__register_int(H5T_PERS_HARD, "ullong_flt", native_ullong, native_float, H5T__conv_ullong_float);
1206     status |= H5T__register_int(H5T_PERS_HARD, "ullong_dbl", native_ullong, native_double, H5T__conv_ullong_double);
1207 #ifdef H5T_CONV_INTERNAL_ULLONG_LDOUBLE
1208     status |= H5T__register_int(H5T_PERS_HARD, "ullong_ldbl", native_ullong, native_ldouble, H5T__conv_ullong_ldouble);
1209 #endif /* H5T_CONV_INTERNAL_ULLONG_LDOUBLE */
1210 
1211     /* From floats to char */
1212     status |= H5T__register_int(H5T_PERS_HARD, "flt_schar", native_float, native_schar, H5T__conv_float_schar);
1213     status |= H5T__register_int(H5T_PERS_HARD, "dbl_schar", native_double, native_schar, H5T__conv_double_schar);
1214     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_schar", native_ldouble, native_schar, H5T__conv_ldouble_schar);
1215 
1216     /* From floats to unsigned char */
1217     status |= H5T__register_int(H5T_PERS_HARD, "flt_uchar", native_float, native_uchar, H5T__conv_float_uchar);
1218     status |= H5T__register_int(H5T_PERS_HARD, "dbl_uchar", native_double, native_uchar, H5T__conv_double_uchar);
1219     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_uchar", native_ldouble, native_uchar, H5T__conv_ldouble_uchar);
1220 
1221     /* From floats to short */
1222     status |= H5T__register_int(H5T_PERS_HARD, "flt_short", native_float, native_short, H5T__conv_float_short);
1223     status |= H5T__register_int(H5T_PERS_HARD, "dbl_short", native_double, native_short, H5T__conv_double_short);
1224     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_short", native_ldouble, native_short, H5T__conv_ldouble_short);
1225 
1226     /* From floats to unsigned short */
1227     status |= H5T__register_int(H5T_PERS_HARD, "flt_ushort", native_float, native_ushort, H5T__conv_float_ushort);
1228     status |= H5T__register_int(H5T_PERS_HARD, "dbl_ushort", native_double, native_ushort, H5T__conv_double_ushort);
1229     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_ushort", native_ldouble, native_ushort, H5T__conv_ldouble_ushort);
1230 
1231     /* From floats to int */
1232     status |= H5T__register_int(H5T_PERS_HARD, "flt_int", native_float, native_int, H5T__conv_float_int);
1233     status |= H5T__register_int(H5T_PERS_HARD, "dbl_int", native_double, native_int, H5T__conv_double_int);
1234     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_int", native_ldouble, native_int, H5T__conv_ldouble_int);
1235 
1236     /* From floats to unsigned int */
1237     status |= H5T__register_int(H5T_PERS_HARD, "flt_uint", native_float, native_uint, H5T__conv_float_uint);
1238     status |= H5T__register_int(H5T_PERS_HARD, "dbl_uint", native_double, native_uint, H5T__conv_double_uint);
1239     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_uint", native_ldouble, native_uint, H5T__conv_ldouble_uint);
1240 
1241     /* From floats to long */
1242     status |= H5T__register_int(H5T_PERS_HARD, "flt_long", native_float, native_long, H5T__conv_float_long);
1243     status |= H5T__register_int(H5T_PERS_HARD, "dbl_long", native_double, native_long, H5T__conv_double_long);
1244     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_long", native_ldouble, native_long, H5T__conv_ldouble_long);
1245 
1246     /* From floats to unsigned long */
1247     status |= H5T__register_int(H5T_PERS_HARD, "flt_ulong", native_float, native_ulong, H5T__conv_float_ulong);
1248     status |= H5T__register_int(H5T_PERS_HARD, "dbl_ulong", native_double, native_ulong, H5T__conv_double_ulong);
1249     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_ulong", native_ldouble, native_ulong, H5T__conv_ldouble_ulong);
1250 
1251     /* From floats to long long */
1252     status |= H5T__register_int(H5T_PERS_HARD, "flt_llong", native_float, native_llong, H5T__conv_float_llong);
1253     status |= H5T__register_int(H5T_PERS_HARD, "dbl_llong", native_double, native_llong, H5T__conv_double_llong);
1254 #ifdef H5T_CONV_INTERNAL_LDOUBLE_LLONG
1255     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_llong", native_ldouble, native_llong, H5T__conv_ldouble_llong);
1256 #endif /* H5T_CONV_INTERNAL_LDOUBLE_LLONG */
1257 
1258     /* From floats to unsigned long long */
1259     status |= H5T__register_int(H5T_PERS_HARD, "flt_ullong", native_float, native_ullong, H5T__conv_float_ullong);
1260     status |= H5T__register_int(H5T_PERS_HARD, "dbl_ullong", native_double, native_ullong, H5T__conv_double_ullong);
1261 #if H5T_CONV_INTERNAL_LDOUBLE_ULLONG
1262     status |= H5T__register_int(H5T_PERS_HARD, "ldbl_ullong", native_ldouble, native_ullong, H5T__conv_ldouble_ullong);
1263 #endif /* H5T_CONV_INTERNAL_LDOUBLE_ULLONG */
1264 
1265     /*
1266      * The special no-op conversion is the fastest, so we list it last. The
1267      * data types we use are not important as long as the source and
1268      * destination are equal.
1269      */
1270     status |= H5T__register_int(H5T_PERS_HARD, "no-op", native_int, native_int, H5T__conv_noop);
1271 
1272     /* Initialize the +/- Infinity values for floating-point types */
1273     status |= H5T__init_inf();
1274 
1275     if(status < 0)
1276         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function(s)")
1277 
1278     /* Register datatype creation property class properties here.  See similar
1279      * code in H5D__init_package(), etc. for example.
1280      */
1281 
1282     /* Only register the default property list if it hasn't been created yet */
1283     if(H5P_LST_DATATYPE_CREATE_ID_g == (-1)) {
1284         /* ========== Datatype Creation Property Class Initialization ============*/
1285         HDassert(H5P_CLS_DATATYPE_CREATE_g != NULL);
1286 
1287         /* Register the default datatype creation property list */
1288         if((H5P_LST_DATATYPE_CREATE_ID_g = H5P_create_id(H5P_CLS_DATATYPE_CREATE_g, FALSE)) < 0)
1289              HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
1290     } /* end if */
1291 
1292     /* Mark "top" of interface as initialized, too */
1293     H5T_top_package_initialize_s = TRUE;
1294 
1295 done:
1296     /* General cleanup */
1297     if(compound != NULL)
1298         (void)H5T_close_real(compound);
1299     if(enum_type != NULL)
1300         (void)H5T_close_real(enum_type);
1301     if(vlen != NULL)
1302         (void)H5T_close_real(vlen);
1303     if(array != NULL)
1304         (void)H5T_close_real(array);
1305 
1306     /* Error cleanup */
1307     if(ret_value < 0) {
1308         if(dt) {
1309             /* Check if we should call H5T_close_real or H5FL_FREE */
1310             if(copied_dtype)
1311                 (void)H5T_close_real(dt);
1312             else {
1313                 dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
1314                 dt = H5FL_FREE(H5T_t, dt);
1315             } /* end else */
1316         } /* end if */
1317     } /* end if */
1318 
1319     FUNC_LEAVE_NOAPI(ret_value)
1320 } /* end H5T__init_package() */
1321 
1322 
1323 /*-------------------------------------------------------------------------
1324  * Function:   H5T__unlock_cb
1325  *
1326  * Purpose:    Clear the immutable flag for a datatype.  This function is
1327  *             called when the library is closing in order to unlock all
1328  *             registered datatypes and thus make them free-able.
1329  *
1330  * Return:     Non-negative on success/Negative on failure
1331  *
1332  * Programmer:  Robb Matzke
1333  *              Monday, April 27, 1998
1334  *
1335  *-------------------------------------------------------------------------
1336  */
1337 static int
H5T__unlock_cb(void * _dt,hid_t H5_ATTR_UNUSED id,void * _udata)1338 H5T__unlock_cb(void *_dt, hid_t H5_ATTR_UNUSED id, void *_udata)
1339 {
1340     H5T_t    *dt = (H5T_t *)_dt;
1341     int      *n = (int *)_udata;
1342 
1343     FUNC_ENTER_STATIC_NOERR
1344 
1345     HDassert(dt && dt->shared);
1346 
1347     if(H5T_STATE_IMMUTABLE==dt->shared->state) {
1348         dt->shared->state = H5T_STATE_RDONLY;
1349         (*n)++;
1350     } /* end if */
1351 
1352     FUNC_LEAVE_NOAPI(SUCCEED)
1353 } /* end H5T__unlock_cb() */
1354 
1355 
1356 /*-------------------------------------------------------------------------
1357  * Function:   H5T_top_term_package
1358  *
1359  * Purpose:    Close the "top" of the interface, releasing IDs, etc.
1360  *
1361  * Return:     Success:    Positive if any action might have caused a
1362  *                            change in some other interface; zero otherwise.
1363  *             Failure:    Negative
1364  *
1365  * Programmer:  Quincey Koziol
1366  *              Thursday, September 10, 2015
1367  *
1368  *-------------------------------------------------------------------------
1369  */
1370 int
H5T_top_term_package(void)1371 H5T_top_term_package(void)
1372 {
1373     int    n = 0;
1374 
1375     FUNC_ENTER_NOAPI_NOINIT_NOERR
1376 
1377     if(H5T_top_package_initialize_s) {
1378         /* Unregister all conversion functions */
1379         if(H5T_g.path) {
1380             int i, nprint = 0;
1381 
1382             for(i = 0; i < H5T_g.npaths; i++) {
1383                 H5T_path_t *path;
1384 
1385                 path = H5T_g.path[i];
1386                 HDassert(path);
1387                 if(path->conv.u.app_func) {
1388                     H5T__print_stats(path, &nprint/*in,out*/);
1389                     path->cdata.command = H5T_CONV_FREE;
1390                     if(path->conv.is_app) {
1391                         if((path->conv.u.app_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
1392 #ifdef H5T_DEBUG
1393                             if (H5DEBUG(T)) {
1394                                 fprintf(H5DEBUG(T), "H5T: conversion function "
1395                                         "0x%08lx failed to free private data for "
1396                                         "%s (ignored)\n",
1397                                         (unsigned long)(path->conv.u.app_func), path->name);
1398                             } /* end if */
1399 #endif
1400                             H5E_clear_stack(NULL); /*ignore the error*/
1401                         } /* end if */
1402                     } /* end if */
1403                     else {
1404                         if((path->conv.u.lib_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
1405 #ifdef H5T_DEBUG
1406                             if (H5DEBUG(T)) {
1407                                 fprintf(H5DEBUG(T), "H5T: conversion function "
1408                                         "0x%08lx failed to free private data for "
1409                                         "%s (ignored)\n",
1410                                         (unsigned long)(path->conv.u.lib_func), path->name);
1411                             } /* end if */
1412 #endif
1413                             H5E_clear_stack(NULL); /*ignore the error*/
1414                         } /* end if */
1415                     } /* end else */
1416                 } /* end if */
1417 
1418                 if(path->src)
1419                     (void)H5T_close_real(path->src);
1420                 if(path->dst)
1421                     (void)H5T_close_real(path->dst);
1422                 path = H5FL_FREE(H5T_path_t, path);
1423                 H5T_g.path[i] = NULL;
1424             } /* end for */
1425 
1426             /* Clear conversion tables */
1427             H5T_g.path = (H5T_path_t **)H5MM_xfree(H5T_g.path);
1428             H5T_g.npaths = 0;
1429             H5T_g.apaths = 0;
1430             H5T_g.soft = (H5T_soft_t *)H5MM_xfree(H5T_g.soft);
1431             H5T_g.nsoft = 0;
1432             H5T_g.asoft = 0;
1433 
1434             n++;
1435         } /* end if */
1436 
1437         /* Unlock all datatypes, then free them */
1438         /* note that we are ignoring the return value from H5I_iterate() */
1439         /* Also note that we are incrementing 'n' in the callback */
1440         H5I_iterate(H5I_DATATYPE, H5T__unlock_cb, &n, FALSE);
1441 
1442         /* Release all datatype IDs */
1443         if(H5I_nmembers(H5I_DATATYPE) > 0) {
1444             (void)H5I_clear_type(H5I_DATATYPE, FALSE, FALSE);
1445             n++; /*H5I*/
1446         } /* end if */
1447 
1448         /* Reset all the datatype IDs */
1449         if(H5T_IEEE_F32BE_g > 0) {
1450             H5T_IEEE_F32BE_g            = FAIL;
1451             H5T_IEEE_F32LE_g            = FAIL;
1452             H5T_IEEE_F64BE_g            = FAIL;
1453             H5T_IEEE_F64LE_g            = FAIL;
1454 
1455             H5T_STD_I8BE_g              = FAIL;
1456             H5T_STD_I8LE_g              = FAIL;
1457             H5T_STD_I16BE_g             = FAIL;
1458             H5T_STD_I16LE_g             = FAIL;
1459             H5T_STD_I32BE_g             = FAIL;
1460             H5T_STD_I32LE_g             = FAIL;
1461             H5T_STD_I64BE_g             = FAIL;
1462             H5T_STD_I64LE_g             = FAIL;
1463             H5T_STD_U8BE_g              = FAIL;
1464             H5T_STD_U8LE_g              = FAIL;
1465             H5T_STD_U16BE_g             = FAIL;
1466             H5T_STD_U16LE_g             = FAIL;
1467             H5T_STD_U32BE_g             = FAIL;
1468             H5T_STD_U32LE_g             = FAIL;
1469             H5T_STD_U64BE_g             = FAIL;
1470             H5T_STD_U64LE_g             = FAIL;
1471             H5T_STD_B8BE_g              = FAIL;
1472             H5T_STD_B8LE_g              = FAIL;
1473             H5T_STD_B16BE_g             = FAIL;
1474             H5T_STD_B16LE_g             = FAIL;
1475             H5T_STD_B32BE_g             = FAIL;
1476             H5T_STD_B32LE_g             = FAIL;
1477             H5T_STD_B64BE_g             = FAIL;
1478             H5T_STD_B64LE_g             = FAIL;
1479             H5T_STD_REF_OBJ_g           = FAIL;
1480             H5T_STD_REF_DSETREG_g       = FAIL;
1481 
1482             H5T_UNIX_D32BE_g            = FAIL;
1483             H5T_UNIX_D32LE_g            = FAIL;
1484             H5T_UNIX_D64BE_g            = FAIL;
1485             H5T_UNIX_D64LE_g            = FAIL;
1486 
1487             H5T_C_S1_g                  = FAIL;
1488 
1489             H5T_FORTRAN_S1_g            = FAIL;
1490 
1491             H5T_NATIVE_SCHAR_g          = FAIL;
1492             H5T_NATIVE_UCHAR_g          = FAIL;
1493             H5T_NATIVE_SHORT_g          = FAIL;
1494             H5T_NATIVE_USHORT_g         = FAIL;
1495             H5T_NATIVE_INT_g            = FAIL;
1496             H5T_NATIVE_UINT_g           = FAIL;
1497             H5T_NATIVE_LONG_g           = FAIL;
1498             H5T_NATIVE_ULONG_g          = FAIL;
1499             H5T_NATIVE_LLONG_g          = FAIL;
1500             H5T_NATIVE_ULLONG_g         = FAIL;
1501             H5T_NATIVE_FLOAT_g          = FAIL;
1502             H5T_NATIVE_DOUBLE_g         = FAIL;
1503 #if H5_SIZEOF_LONG_DOUBLE !=0
1504             H5T_NATIVE_LDOUBLE_g        = FAIL;
1505 #endif
1506             H5T_NATIVE_B8_g             = FAIL;
1507             H5T_NATIVE_B16_g            = FAIL;
1508             H5T_NATIVE_B32_g            = FAIL;
1509             H5T_NATIVE_B64_g            = FAIL;
1510             H5T_NATIVE_OPAQUE_g         = FAIL;
1511             H5T_NATIVE_HADDR_g          = FAIL;
1512             H5T_NATIVE_HSIZE_g          = FAIL;
1513             H5T_NATIVE_HSSIZE_g         = FAIL;
1514             H5T_NATIVE_HERR_g           = FAIL;
1515             H5T_NATIVE_HBOOL_g          = FAIL;
1516 
1517             H5T_NATIVE_INT8_g           = FAIL;
1518             H5T_NATIVE_UINT8_g          = FAIL;
1519             H5T_NATIVE_INT_LEAST8_g     = FAIL;
1520             H5T_NATIVE_UINT_LEAST8_g    = FAIL;
1521             H5T_NATIVE_INT_FAST8_g      = FAIL;
1522             H5T_NATIVE_UINT_FAST8_g     = FAIL;
1523 
1524             H5T_NATIVE_INT16_g          = FAIL;
1525             H5T_NATIVE_UINT16_g         = FAIL;
1526             H5T_NATIVE_INT_LEAST16_g    = FAIL;
1527             H5T_NATIVE_UINT_LEAST16_g   = FAIL;
1528             H5T_NATIVE_INT_FAST16_g     = FAIL;
1529             H5T_NATIVE_UINT_FAST16_g    = FAIL;
1530 
1531             H5T_NATIVE_INT32_g          = FAIL;
1532             H5T_NATIVE_UINT32_g         = FAIL;
1533             H5T_NATIVE_INT_LEAST32_g    = FAIL;
1534             H5T_NATIVE_UINT_LEAST32_g   = FAIL;
1535             H5T_NATIVE_INT_FAST32_g     = FAIL;
1536             H5T_NATIVE_UINT_FAST32_g    = FAIL;
1537 
1538             H5T_NATIVE_INT64_g          = FAIL;
1539             H5T_NATIVE_UINT64_g         = FAIL;
1540             H5T_NATIVE_INT_LEAST64_g    = FAIL;
1541             H5T_NATIVE_UINT_LEAST64_g   = FAIL;
1542             H5T_NATIVE_INT_FAST64_g     = FAIL;
1543             H5T_NATIVE_UINT_FAST64_g    = FAIL;
1544 
1545             n++;
1546         } /* end if */
1547 
1548     /* Mark "top" of interface as closed */
1549         if(0 == n)
1550             H5T_top_package_initialize_s = FALSE;
1551     } /* end if */
1552 
1553     FUNC_LEAVE_NOAPI(n)
1554 } /* end H5T_top_term_package() */
1555 
1556 
1557 /*-------------------------------------------------------------------------
1558  * Function:   H5T_term_package
1559  *
1560  * Purpose:    Close this interface.
1561  *
1562  * Note:    Finishes shutting down the interface, after
1563  *          H5T_top_term_package() is called
1564  *
1565  * Return:   Success:    Positive if any action might have caused a
1566  *                change in some other interface; zero
1567  *                otherwise.
1568  *           Failure:    Negative
1569  *
1570  * Programmer:  Robb Matzke
1571  *              Friday, November 20, 1998
1572  *
1573  *-------------------------------------------------------------------------
1574  */
1575 int
H5T_term_package(void)1576 H5T_term_package(void)
1577 {
1578     int    n = 0;
1579 
1580     FUNC_ENTER_NOAPI_NOINIT_NOERR
1581 
1582     if(H5_PKG_INIT_VAR) {
1583         /* Sanity check */
1584         HDassert(0 == H5I_nmembers(H5I_DATATYPE));
1585         HDassert(FALSE == H5T_top_package_initialize_s);
1586 
1587         /* Destroy the datatype object id group */
1588         n += (H5I_dec_type_ref(H5I_DATATYPE) > 0);
1589 
1590         /* Mark interface as closed */
1591         if(0 == n)
1592             H5_PKG_INIT_VAR = FALSE;
1593     } /* end if */
1594 
1595     FUNC_LEAVE_NOAPI(n)
1596 } /* end H5T_term_package() */
1597 
1598 
1599 /*-------------------------------------------------------------------------
1600  * Function:   H5Tcreate
1601  *
1602  * Purpose:    Create a new type and initialize it to reasonable values.
1603  *             The type is a member of type class TYPE and is SIZE bytes.
1604  *
1605  * Return:    Success:    A new type identifier.
1606  *
1607  *            Failure:    Negative
1608  *
1609  * Errors:
1610  *        ARGS      BADVALUE    Invalid size.
1611  *        DATATYPE  CANTINIT    Can't create type.
1612  *        DATATYPE  CANTREGISTER    Can't register datatype atom.
1613  *
1614  * Programmer:    Robb Matzke
1615  *        Friday, December  5, 1997
1616  *-------------------------------------------------------------------------
1617  */
1618 hid_t
H5Tcreate(H5T_class_t type,size_t size)1619 H5Tcreate(H5T_class_t type, size_t size)
1620 {
1621     H5T_t    *dt = NULL;     /* New datatype constructed */
1622     hid_t    ret_value;      /* Return value */
1623 
1624     FUNC_ENTER_API(FAIL)
1625     H5TRACE2("i", "Ttz", type, size);
1626 
1627     /* check args. We support string (fixed-size or variable-length) now. */
1628     if(size <= 0 && size != H5T_VARIABLE)
1629     HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive")
1630 
1631     /* create the type */
1632     if(NULL == (dt = H5T__create(type, size)))
1633     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create type")
1634 
1635     /* Get an ID for the datatype */
1636     if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
1637     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype ID")
1638 
1639 done:
1640     FUNC_LEAVE_API(ret_value)
1641 } /* end H5Tcreate() */
1642 
1643 
1644 /*-------------------------------------------------------------------------
1645  * Function:    H5Tcopy
1646  *
1647  * Purpose:    Copies a datatype.  The resulting datatype is not locked.
1648  *        The datatype should be closed when no longer needed by
1649  *        calling H5Tclose().
1650  *
1651  * Return:    Success:    The ID of a new datatype.
1652  *
1653  *            Failure:    Negative
1654  *
1655  * Programmer:    Robb Matzke
1656  *        Tuesday, December  9, 1997
1657  *
1658  * Modifications:
1659  *
1660  *     Robb Matzke, 4 Jun 1998
1661  *    The returned type is always transient and unlocked.  If the TYPE_ID
1662  *    argument is a dataset instead of a datatype then this function
1663  *    returns a transient, modifiable datatype which is a copy of the
1664  *    dataset's datatype.
1665  *
1666  *-------------------------------------------------------------------------
1667  */
1668 hid_t
H5Tcopy(hid_t type_id)1669 H5Tcopy(hid_t type_id)
1670 {
1671     H5T_t    *dt;                    /* Pointer to the datatype to copy */
1672     H5T_t    *new_dt = NULL;
1673     hid_t    ret_value;              /* Return value */
1674 
1675     FUNC_ENTER_API(H5I_INVALID_HID)
1676     H5TRACE1("i", "i", type_id);
1677 
1678     switch(H5I_get_type(type_id)) {
1679         case H5I_DATATYPE:
1680             /* The argument is a datatype handle */
1681             if(NULL == (dt = (H5T_t *)H5I_object(type_id)))
1682                 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a datatype")
1683             break;
1684 
1685         case H5I_DATASET:
1686             {
1687                 H5D_t    *dset;          /* Dataset for datatype */
1688 
1689                 /* The argument is a dataset handle */
1690                 if(NULL == (dset = (H5D_t *)H5I_object(type_id)))
1691                     HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a dataset")
1692                 if(NULL == (dt = H5D_typeof(dset)))
1693                     HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5I_INVALID_HID, "unable to get the dataset datatype")
1694             }
1695             break;
1696 
1697         case H5I_UNINIT:
1698         case H5I_BADID:
1699         case H5I_FILE:
1700         case H5I_GROUP:
1701         case H5I_DATASPACE:
1702         case H5I_ATTR:
1703         case H5I_REFERENCE:
1704         case H5I_VFL:
1705         case H5I_GENPROP_CLS:
1706         case H5I_GENPROP_LST:
1707         case H5I_ERROR_CLASS:
1708         case H5I_ERROR_MSG:
1709         case H5I_ERROR_STACK:
1710         case H5I_NTYPES:
1711         default:
1712             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a datatype or dataset")
1713     } /* end switch */
1714 
1715     /* Copy datatype */
1716     if(NULL == (new_dt = H5T_copy(dt, H5T_COPY_TRANSIENT)))
1717         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5I_INVALID_HID, "unable to copy");
1718 
1719     /* Atomize result */
1720     if((ret_value = H5I_register(H5I_DATATYPE, new_dt, TRUE)) < 0)
1721         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register datatype atom")
1722 
1723 done:
1724     if(ret_value < 0)
1725         if(new_dt && H5T_close_real(new_dt) < 0)
1726             HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to release datatype info")
1727 
1728     FUNC_LEAVE_API(ret_value)
1729 } /* end H5Tcopy() */
1730 
1731 
1732 /*-------------------------------------------------------------------------
1733  * Function:    H5Tclose
1734  *
1735  * Purpose:    Frees a datatype and all associated memory.
1736  *
1737  * Return:    Non-negative on success/Negative on failure
1738  *
1739  * Programmer:    Robb Matzke
1740  *        Tuesday, December  9, 1997
1741  *-------------------------------------------------------------------------
1742  */
1743 herr_t
H5Tclose(hid_t type_id)1744 H5Tclose(hid_t type_id)
1745 {
1746     H5T_t    *dt;                    /* Pointer to datatype to close */
1747     herr_t      ret_value = SUCCEED;       /* Return value */
1748 
1749     FUNC_ENTER_API(FAIL)
1750     H5TRACE1("e", "i", type_id);
1751 
1752     /* Check args */
1753     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
1754         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1755     if(H5T_STATE_IMMUTABLE == dt->shared->state)
1756         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype")
1757 
1758     /* When the reference count reaches zero the resources are freed */
1759     if(H5I_dec_app_ref(type_id) < 0)
1760         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id")
1761 
1762 done:
1763     FUNC_LEAVE_API(ret_value)
1764 } /* end H5Tclose() */
1765 
1766 
1767 /*-------------------------------------------------------------------------
1768  * Function:  H5Tequal
1769  *
1770  * Purpose:   Determines if two datatypes are equal.
1771  *
1772  * Return:    Success:    TRUE if equal, FALSE if unequal
1773  *
1774  *            Failure:    Negative
1775  *
1776  * Programmer:    Robb Matzke
1777  *        Wednesday, December 10, 1997
1778  *
1779  *-------------------------------------------------------------------------
1780  */
1781 htri_t
H5Tequal(hid_t type1_id,hid_t type2_id)1782 H5Tequal(hid_t type1_id, hid_t type2_id)
1783 {
1784     const H5T_t    *dt1;           /* Pointer to first datatype */
1785     const H5T_t    *dt2;           /* Pointer to second datatype */
1786     htri_t         ret_value;      /* Return value */
1787 
1788     FUNC_ENTER_API(FAIL)
1789     H5TRACE2("t", "ii", type1_id, type2_id);
1790 
1791     /* check args */
1792     if(NULL == (dt1 = (H5T_t *)H5I_object_verify(type1_id, H5I_DATATYPE)))
1793         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1794     if(NULL == (dt2 = (H5T_t *)H5I_object_verify(type2_id, H5I_DATATYPE)))
1795         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1796 
1797     ret_value = (0 == H5T_cmp(dt1, dt2, FALSE)) ? TRUE : FALSE;
1798 
1799 done:
1800     FUNC_LEAVE_API(ret_value)
1801 } /* end H5Tequal() */
1802 
1803 
1804 /*-------------------------------------------------------------------------
1805  * Function:    H5Tlock
1806  *
1807  * Purpose:    Locks a type, making it read only and non-destructable.
1808  *        This is normally done by the library for predefined datatypes so
1809  *        the application doesn't inadvertently change or delete a
1810  *        predefined type.
1811  *
1812  *        Once a datatype is locked it can never be unlocked unless
1813  *        the entire library is closed.
1814  *
1815  * Return:    Non-negative on success/Negative on failure
1816  *
1817  * Programmer:    Robb Matzke
1818  *        Friday, January     9, 1998
1819  *
1820  * Modifications:
1821  *
1822  *     Robb Matzke, 1 Jun 1998
1823  *    It is illegal to lock a named datatype since we must allow named
1824  *    types to be closed (to release file resources) but locking a type
1825  *    prevents that.
1826  *-------------------------------------------------------------------------
1827  */
1828 herr_t
H5Tlock(hid_t type_id)1829 H5Tlock(hid_t type_id)
1830 {
1831     H5T_t       *dt;                    /* Datatype to operate on */
1832     herr_t      ret_value = SUCCEED;    /* Return value */
1833 
1834     FUNC_ENTER_API(FAIL)
1835     H5TRACE1("e", "i", type_id);
1836 
1837     /* Check args */
1838     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
1839         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1840     if(H5T_STATE_NAMED==dt->shared->state || H5T_STATE_OPEN==dt->shared->state)
1841         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to lock named datatype")
1842 
1843     if(H5T_lock(dt, TRUE) < 0)
1844         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
1845 
1846 done:
1847     FUNC_LEAVE_API(ret_value)
1848 } /* end H5Tlock() */
1849 
1850 
1851 /*-------------------------------------------------------------------------
1852  * Function:  H5Tget_class
1853  *
1854  * Purpose:   Returns the datatype class identifier for datatype TYPE_ID.
1855  *
1856  * Return:    Success:    One of the non-negative datatype class constants.
1857  *
1858  *            Failure:    H5T_NO_CLASS (Negative)
1859  *
1860  * Programmer:    Robb Matzke
1861  *        Monday, December  8, 1997
1862  *
1863  *-------------------------------------------------------------------------
1864  */
1865 H5T_class_t
H5Tget_class(hid_t type_id)1866 H5Tget_class(hid_t type_id)
1867 {
1868     H5T_t       *dt;            /* Pointer to datatype */
1869     H5T_class_t ret_value;      /* Return value */
1870 
1871     FUNC_ENTER_API(H5T_NO_CLASS)
1872     H5TRACE1("Tt", "i", type_id);
1873 
1874     /* Check args */
1875     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
1876         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
1877 
1878     /* Set return value */
1879     ret_value = H5T_get_class(dt, FALSE);
1880 
1881 done:
1882     FUNC_LEAVE_API(ret_value)
1883 } /* end H5Tget_class() */
1884 
1885 
1886 /*-------------------------------------------------------------------------
1887  * Function:  H5T_get_class
1888  *
1889  * Purpose:   Returns the data type class identifier for a datatype ptr.
1890  *
1891  * Return:    Success:    One of the non-negative data type class constants.
1892  *
1893  *            Failure:    H5T_NO_CLASS (Negative)
1894  *
1895  * Programmer:    Robb Matzke
1896  *        Monday, December  8, 1997
1897  *
1898  * Modifications:
1899  *      Broke out from H5Tget_class - QAK - 6/4/99
1900  *
1901  *-------------------------------------------------------------------------
1902  */
1903 H5T_class_t
H5T_get_class(const H5T_t * dt,htri_t internal)1904 H5T_get_class(const H5T_t *dt, htri_t internal)
1905 {
1906     H5T_class_t ret_value = H5T_NO_CLASS;       /* Return value */
1907 
1908     FUNC_ENTER_NOAPI(H5T_NO_CLASS)
1909 
1910     HDassert(dt);
1911 
1912     /* Externally, a VL string is a string; internally, a VL string is a VL. */
1913     if(internal) {
1914         ret_value=dt->shared->type;
1915     }
1916     else {
1917         if(H5T_IS_VL_STRING(dt->shared))
1918             ret_value=H5T_STRING;
1919         else
1920             ret_value=dt->shared->type;
1921     }
1922 
1923 done:
1924     FUNC_LEAVE_NOAPI(ret_value)
1925 }   /* end H5T_get_class() */
1926 
1927 
1928 /*-------------------------------------------------------------------------
1929  * Function:   H5Tdetect_class
1930  *
1931  * Purpose:    Check whether a datatype contains (or is) a certain type of
1932  *             datatype.
1933  *
1934  * Return:     TRUE (1) or FALSE (0) on success/Negative on failure
1935  *
1936  * Programmer:    Quincey Koziol
1937  *        Wednesday, November 29, 2000
1938  *-------------------------------------------------------------------------
1939  */
1940 htri_t
H5Tdetect_class(hid_t type,H5T_class_t cls)1941 H5Tdetect_class(hid_t type, H5T_class_t cls)
1942 {
1943     H5T_t       *dt;            /* Datatype to query */
1944     htri_t      ret_value;      /* Return value */
1945 
1946     FUNC_ENTER_API(FAIL)
1947     H5TRACE2("t", "iTt", type, cls);
1948 
1949     /* Check args */
1950     if(NULL == (dt = (H5T_t *)H5I_object_verify(type,H5I_DATATYPE)))
1951         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
1952     if(!(cls > H5T_NO_CLASS && cls < H5T_NCLASSES))
1953         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype class")
1954 
1955     /* Set return value */
1956     if((ret_value = H5T_detect_class(dt, cls, TRUE)) < 0)
1957         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5T_NO_CLASS, "can't get datatype class")
1958 
1959 done:
1960     FUNC_LEAVE_API(ret_value)
1961 } /* end H5Tdetect_class() */
1962 
1963 
1964 /*-------------------------------------------------------------------------
1965  * Function:   H5T_detect_class
1966  *
1967  * Purpose:    Check whether a datatype contains (or is) a certain type of
1968  *             datatype.
1969  *
1970  * Return:     TRUE (1) or FALSE (0) on success/Negative on failure
1971  *
1972  * Programmer:    Quincey Koziol
1973  *        Wednesday, November 29, 2000
1974  *
1975  * Modifications:
1976  *              Raymond Lu
1977  *              4 December 2009
1978  *              Added a flag as a parameter to indicate whether the caller is
1979  *              H5Tdetect_class.  I also added the check for VL string type
1980  *              just like the public function.  Because we want to tell users
1981  *              VL string is a string type but we treat it as a VL type
1982  *              internally, H5T_detect_class needs to know where the caller
1983  *              is from.
1984  *-------------------------------------------------------------------------
1985  */
1986 htri_t
H5T_detect_class(const H5T_t * dt,H5T_class_t cls,hbool_t from_api)1987 H5T_detect_class(const H5T_t *dt, H5T_class_t cls, hbool_t from_api)
1988 {
1989     unsigned    i;
1990     htri_t      ret_value = FALSE;        /* Return value */
1991 
1992     FUNC_ENTER_NOAPI(FAIL)
1993 
1994     HDassert(dt);
1995     HDassert(cls > H5T_NO_CLASS && cls < H5T_NCLASSES);
1996 
1997     /* Consider VL string as a string for API, as a VL for internal use. */
1998     /* (note that this check must be performed before checking if the VL
1999      *  string belongs to the H5T_VLEN class, which would otherwise return
2000      *  true. -QAK)
2001      */
2002     if(from_api && H5T_IS_VL_STRING(dt->shared))
2003         HGOTO_DONE(H5T_STRING == cls);
2004 
2005     /* Check if this type is the correct type */
2006     if(dt->shared->type == cls)
2007         HGOTO_DONE(TRUE);
2008 
2009     /* check for types that might have the correct type as a component */
2010     switch(dt->shared->type) {
2011         case H5T_COMPOUND:
2012             for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
2013                 htri_t nested_ret;      /* Return value from nested call */
2014 
2015                 /* Check if this field's type is the correct type */
2016                 if(dt->shared->u.compnd.memb[i].type->shared->type == cls)
2017                     HGOTO_DONE(TRUE);
2018 
2019                 /* Recurse if it's VL, compound, enum or array */
2020                 if(H5T_IS_COMPLEX(dt->shared->u.compnd.memb[i].type->shared->type))
2021                     if((nested_ret = H5T_detect_class(dt->shared->u.compnd.memb[i].type, cls, from_api)) != FALSE)
2022                         HGOTO_DONE(nested_ret);
2023             } /* end for */
2024             break;
2025 
2026         case H5T_ARRAY:
2027         case H5T_VLEN:
2028         case H5T_ENUM:
2029             HGOTO_DONE(H5T_detect_class(dt->shared->parent, cls, from_api));
2030             break;
2031         case H5T_NO_CLASS:
2032         case H5T_INTEGER:
2033         case H5T_FLOAT:
2034         case H5T_TIME:
2035         case H5T_STRING:
2036         case H5T_BITFIELD:
2037         case H5T_OPAQUE:
2038         case H5T_REFERENCE:
2039         case H5T_NCLASSES:
2040         default:
2041             break;
2042     } /* end if */
2043 
2044 done:
2045     FUNC_LEAVE_NOAPI(ret_value)
2046 } /* end H5T_detect_class() */
2047 
2048 
2049 /*-------------------------------------------------------------------------
2050  * Function:  H5Tis_variable_str
2051  *
2052  * Purpose:   Check whether a datatype is a variable-length string
2053  *
2054  * Return:    TRUE (1) or FALSE (0) on success/Negative on failure
2055  *
2056  * Programmer:    Raymond Lu
2057  *        November 4, 2002
2058  *
2059  *-------------------------------------------------------------------------
2060  */
2061 htri_t
H5Tis_variable_str(hid_t dtype_id)2062 H5Tis_variable_str(hid_t dtype_id)
2063 {
2064     H5T_t       *dt;            /* Datatype to query */
2065     htri_t      ret_value;      /* Return value */
2066 
2067     FUNC_ENTER_API(FAIL)
2068     H5TRACE1("t", "i", dtype_id);
2069 
2070     /* Check args */
2071     if(NULL == (dt = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
2072         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
2073 
2074     /* Set return value */
2075     if((ret_value = H5T_is_variable_str(dt)) < 0)
2076         HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't determine if datatype is VL-string")
2077 
2078 done:
2079     FUNC_LEAVE_API(ret_value)
2080 } /* end H5Tis_variable_str() */
2081 
2082 
2083 /*-------------------------------------------------------------------------
2084  * Function:  H5T_is_variable_str
2085  *
2086  * Purpose:   Check whether a datatype is a variable-length string
2087  *
2088  * Return:    TRUE (1) or FALSE (0) on success/Negative on failure
2089  *
2090  * Programmer:    Quincey Koziol
2091  *        October 17, 2007
2092  *
2093  *-------------------------------------------------------------------------
2094  */
2095 htri_t
H5T_is_variable_str(const H5T_t * dt)2096 H5T_is_variable_str(const H5T_t *dt)
2097 {
2098     FUNC_ENTER_NOAPI_NOINIT_NOERR
2099 
2100     FUNC_LEAVE_NOAPI(H5T_IS_VL_STRING(dt->shared))
2101 } /* end H5T_is_variable_str() */
2102 
2103 
2104 /*-------------------------------------------------------------------------
2105  * Function:  H5Tget_size
2106  *
2107  * Purpose:   Determines the total size of a datatype in bytes.
2108  *
2109  * Return:    Success:    Size of the datatype in bytes.     The size of
2110  *                datatype is the size of an instance of that
2111  *                datatype.
2112  *
2113  *            Failure:    0 (valid datatypes are never zero size)
2114  *
2115  * Programmer:    Robb Matzke
2116  *        Monday, December  8, 1997
2117  *
2118  *-------------------------------------------------------------------------
2119  */
2120 size_t
H5Tget_size(hid_t type_id)2121 H5Tget_size(hid_t type_id)
2122 {
2123     H5T_t     *dt;            /* Datatype to query */
2124     size_t    ret_value;      /* Return value */
2125 
2126     FUNC_ENTER_API(0)
2127     H5TRACE1("z", "i", type_id);
2128 
2129     /* Check args */
2130     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
2131         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype")
2132 
2133     /* size */
2134     ret_value = H5T_GET_SIZE(dt);
2135 
2136 done:
2137     FUNC_LEAVE_API(ret_value)
2138 } /* end H5Tget_size() */
2139 
2140 
2141 /*-------------------------------------------------------------------------
2142  * Function:    H5Tset_size
2143  *
2144  * Purpose:    Sets the total size in bytes for a datatype (this operation
2145  *        is not permitted on reference datatypes).  If the size is
2146  *        decreased so that the significant bits of the datatype
2147  *        extend beyond the edge of the new size, then the `offset'
2148  *        property is decreased toward zero.  If the `offset' becomes
2149  *        zero and the significant bits of the datatype still hang
2150  *        over the edge of the new size, then the number of significant
2151  *        bits is decreased.
2152  *
2153  *        Adjusting the size of an H5T_STRING automatically sets the
2154  *        precision to 8*size.
2155  *
2156  *        All datatypes have a positive size.
2157  *
2158  * Return:    Non-negative on success/Negative on failure
2159  *
2160  * Programmer:    Robb Matzke
2161  *        Wednesday, January  7, 1998
2162  *
2163  *-------------------------------------------------------------------------
2164  */
2165 herr_t
H5Tset_size(hid_t type_id,size_t size)2166 H5Tset_size(hid_t type_id, size_t size)
2167 {
2168     H5T_t       *dt;                    /* Datatype to modify */
2169     herr_t      ret_value = SUCCEED;    /* Return value */
2170 
2171     FUNC_ENTER_API(FAIL)
2172     H5TRACE2("e", "iz", type_id, size);
2173 
2174     /* Check args */
2175     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
2176         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
2177     if(H5T_STATE_TRANSIENT!=dt->shared->state)
2178         HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "datatype is read-only")
2179     if(size <= 0 && size != H5T_VARIABLE)
2180         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive")
2181     if(size == H5T_VARIABLE && !H5T_IS_STRING(dt->shared))
2182         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "only strings may be variable length")
2183     if(H5T_ENUM == dt->shared->type && dt->shared->u.enumer.nmembs > 0)
2184         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined")
2185     if(H5T_REFERENCE == dt->shared->type)
2186         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype")
2187 
2188     /* Modify the datatype */
2189     if(H5T__set_size(dt, size) < 0)
2190         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size for datatype")
2191 
2192 done:
2193     FUNC_LEAVE_API(ret_value)
2194 } /* end H5Tset_size() */
2195 
2196 
2197 /*-------------------------------------------------------------------------
2198  * Function:  H5Tget_super
2199  *
2200  * Purpose:   Returns the type from which TYPE is derived. In the case of
2201  *            an enumeration type the return value is an integer type.
2202  *
2203  * Return:    Success:    Type ID for base datatype.
2204  *
2205  *            Failure:    negative
2206  *
2207  * Programmer:    Robb Matzke
2208  *              Wednesday, December 23, 1998
2209  *-------------------------------------------------------------------------
2210  */
2211 hid_t
H5Tget_super(hid_t type)2212 H5Tget_super(hid_t type)
2213 {
2214     H5T_t    *dt;            /* Datatype to query */
2215     H5T_t    *super = NULL;  /* Supertype */
2216     hid_t    ret_value;      /* Return value */
2217 
2218     FUNC_ENTER_API(H5I_INVALID_HID)
2219     H5TRACE1("i", "i", type);
2220 
2221     if(NULL == (dt = (H5T_t *)H5I_object_verify(type,H5I_DATATYPE)))
2222         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a datatype")
2223     if(NULL == (super = H5T_get_super(dt)))
2224         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5I_INVALID_HID, "not a datatype")
2225     if((ret_value = H5I_register(H5I_DATATYPE, super, TRUE)) < 0)
2226         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register parent datatype")
2227 
2228 done:
2229     if(ret_value < 0)
2230         if(super && H5T_close_real(super) < 0)
2231             HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to release super datatype info")
2232 
2233     FUNC_LEAVE_API(ret_value)
2234 } /* end H5Tget_super() */
2235 
2236 
2237 /*-------------------------------------------------------------------------
2238  * Function:  H5T_get_super
2239  *
2240  * Purpose:   Private function for H5Tget_super.  Returns the type from
2241  *            which TYPE is derived. In the case of an enumeration type
2242  *            the return value is an integer type.
2243  *
2244  * Return:    Success:    Data type for base data type.
2245  *
2246  *            Failure:        NULL
2247  *
2248  * Programmer:    Raymond Lu
2249  *              October 9, 2002
2250  *-------------------------------------------------------------------------
2251  */
2252 H5T_t *
H5T_get_super(const H5T_t * dt)2253 H5T_get_super(const H5T_t *dt)
2254 {
2255     H5T_t    *ret_value=NULL;
2256 
2257     FUNC_ENTER_NOAPI(NULL)
2258 
2259     HDassert(dt);
2260 
2261     if (!dt->shared->parent)
2262         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a derived data type");
2263     if (NULL==(ret_value=H5T_copy(dt->shared->parent, H5T_COPY_ALL)))
2264         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy parent data type");
2265 
2266 done:
2267     FUNC_LEAVE_NOAPI(ret_value)
2268 }
2269 
2270 
2271 /*-------------------------------------------------------------------------
2272  * Function:    H5T__register_int
2273  *
2274  * Purpose:    Register a library internal datatype conversion routine.
2275  *
2276  * Return:    Non-negative on success/Negative on failure
2277  *
2278  * Programmer:  Quincey Koziol
2279  *              Wednesday, March 7, 1998
2280  *-------------------------------------------------------------------------
2281  */
2282 static herr_t
H5T__register_int(H5T_pers_t pers,const char * name,H5T_t * src,H5T_t * dst,H5T_lib_conv_t func)2283 H5T__register_int(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
2284     H5T_lib_conv_t func)
2285 {
2286     H5T_conv_func_t conv_func;          /* Conversion function wrapper */
2287     herr_t ret_value = SUCCEED;         /* Return value */
2288 
2289     FUNC_ENTER_STATIC
2290 
2291     /* Check args */
2292     HDassert(H5T_PERS_HARD==pers || H5T_PERS_SOFT==pers);
2293     HDassert(name && *name);
2294     HDassert(src);
2295     HDassert(dst);
2296     HDassert(func);
2297 
2298     /* Set up conversion function wrapper */
2299     conv_func.is_app = FALSE;
2300     conv_func.u.lib_func = func;
2301 
2302     /* Register conversion */
2303     if(H5T__register(pers, name, src, dst, &conv_func) < 0)
2304         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register internal datatype conversion routine")
2305 
2306 done:
2307     FUNC_LEAVE_NOAPI(ret_value)
2308 } /* end H5T__register_int() */
2309 
2310 
2311 /*-------------------------------------------------------------------------
2312  * Function:    H5T__register
2313  *
2314  * Purpose:    Register a hard or soft conversion function for a data type
2315  *        conversion path.  The path is specified by the source and
2316  *        destination data types SRC_ID and DST_ID (for soft functions
2317  *        only the class of these types is important). If FUNC is a
2318  *        hard function then it replaces any previous path; if it's a
2319  *        soft function then it replaces all existing paths to which it
2320  *        applies and is used for any new path to which it applies as
2321  *        long as that path doesn't have a hard function.
2322  *
2323  * Return:    Non-negative on success/Negative on failure
2324  *
2325  * Programmer:    Robb Matzke
2326  *        Friday, January     9, 1998
2327  *-------------------------------------------------------------------------
2328  */
2329 static herr_t
H5T__register(H5T_pers_t pers,const char * name,H5T_t * src,H5T_t * dst,H5T_conv_func_t * conv)2330 H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
2331     H5T_conv_func_t *conv)
2332 {
2333     hid_t         tmp_sid = -1, tmp_did = -1; /*temporary data type IDs    */
2334     H5T_path_t    *old_path = NULL;           /*existing conversion path   */
2335     H5T_path_t    *new_path = NULL;           /*new conversion path        */
2336     H5T_cdata_t   cdata;                      /*temporary conversion data  */
2337     int           nprint=0;                   /*number of paths shut down  */
2338     int           i;                          /*counter                    */
2339     herr_t        ret_value = SUCCEED;        /*return value               */
2340 
2341     FUNC_ENTER_STATIC
2342 
2343     /* Check args */
2344     HDassert(src);
2345     HDassert(dst);
2346     HDassert(conv);
2347     HDassert(H5T_PERS_HARD==pers || H5T_PERS_SOFT==pers);
2348     HDassert(name && *name);
2349 
2350     if(H5T_PERS_HARD == pers) {
2351         /* Only bother to register the path if it's not a no-op path (for this machine) */
2352         if(H5T_cmp(src, dst, FALSE)) {
2353             /* Locate or create a new conversion path */
2354             if(NULL == (new_path = H5T__path_find_real(src, dst, name, conv)))
2355                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to locate/allocate conversion path")
2356 
2357             /*
2358              * Notify all other functions to recalculate private data since some
2359              * functions might cache a list of conversion functions.  For
2360              * instance, the compound type converter caches a list of conversion
2361              * functions for the members, so adding a new function should cause
2362              * the list to be recalculated to use the new function.
2363              */
2364             for(i = 0; i < H5T_g.npaths; i++)
2365                 if(new_path != H5T_g.path[i])
2366                     H5T_g.path[i]->cdata.recalc = TRUE;
2367         } /* end if */
2368     } /* end if */
2369     else {
2370         /* Add function to end of soft list */
2371         if((size_t)H5T_g.nsoft >= H5T_g.asoft) {
2372             size_t na = MAX(32, 2 * H5T_g.asoft);
2373             H5T_soft_t *x;
2374 
2375             if(NULL == (x = (H5T_soft_t *)H5MM_realloc(H5T_g.soft, na * sizeof(H5T_soft_t))))
2376                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
2377             H5T_g.asoft = na;
2378             H5T_g.soft = x;
2379         } /* end if */
2380         HDstrncpy(H5T_g.soft[H5T_g.nsoft].name, name, (size_t)H5T_NAMELEN);
2381         H5T_g.soft[H5T_g.nsoft].name[H5T_NAMELEN - 1] = '\0';
2382         H5T_g.soft[H5T_g.nsoft].src = src->shared->type;
2383         H5T_g.soft[H5T_g.nsoft].dst = dst->shared->type;
2384         H5T_g.soft[H5T_g.nsoft].conv = *conv;
2385         H5T_g.nsoft++;
2386 
2387         /*
2388          * Any existing path (except the no-op path) to which this new soft
2389          * conversion function applies should be replaced by a new path that
2390          * uses this function.
2391          */
2392         for(i = 1; i < H5T_g.npaths; i++) {
2393             old_path = H5T_g.path[i];
2394             HDassert(old_path);
2395 
2396             /* Does the new soft conversion function apply to this path? */
2397             if(old_path->is_hard ||
2398                     old_path->src->shared->type != src->shared->type ||
2399                     old_path->dst->shared->type != dst->shared->type)
2400                 continue;
2401 
2402             if((tmp_sid = H5I_register(H5I_DATATYPE, H5T_copy(old_path->src, H5T_COPY_ALL), FALSE)) < 0 ||
2403                     (tmp_did = H5I_register(H5I_DATATYPE, H5T_copy(old_path->dst, H5T_COPY_ALL), FALSE)) < 0)
2404                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data types for conv query")
2405             HDmemset(&cdata, 0, sizeof cdata);
2406             cdata.command = H5T_CONV_INIT;
2407             if(conv->is_app) {
2408                 if((conv->u.app_func)(tmp_sid, tmp_did, &cdata, (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
2409                     H5I_dec_ref(tmp_sid);
2410                     H5I_dec_ref(tmp_did);
2411                     tmp_sid = tmp_did = -1;
2412                     H5E_clear_stack(NULL);
2413                     continue;
2414                 } /* end if */
2415             } /* end if */
2416             else
2417                 if((conv->u.lib_func)(tmp_sid, tmp_did, &cdata, (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
2418                     H5I_dec_ref(tmp_sid);
2419                     H5I_dec_ref(tmp_did);
2420                     tmp_sid = tmp_did = -1;
2421                     H5E_clear_stack(NULL);
2422                     continue;
2423                 } /* end if */
2424 
2425             /* Create a new conversion path */
2426             if(NULL == (new_path = H5FL_CALLOC(H5T_path_t)))
2427                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
2428             HDstrncpy(new_path->name, name, (size_t)H5T_NAMELEN);
2429             new_path->name[H5T_NAMELEN - 1] = '\0';
2430             if(NULL == (new_path->src = H5T_copy(old_path->src, H5T_COPY_ALL)) ||
2431                     NULL == (new_path->dst=H5T_copy(old_path->dst, H5T_COPY_ALL)))
2432                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy data types")
2433             new_path->conv = *conv;
2434             new_path->is_hard = FALSE;
2435             new_path->cdata = cdata;
2436 
2437             /* Replace previous path */
2438             H5T_g.path[i] = new_path;
2439             new_path = NULL; /*so we don't free it on error*/
2440 
2441             /* Free old path */
2442             H5T__print_stats(old_path, &nprint);
2443             old_path->cdata.command = H5T_CONV_FREE;
2444             if(old_path->conv.is_app) {
2445                 if((old_path->conv.u.app_func)(tmp_sid, tmp_did, &(old_path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
2446 #ifdef H5T_DEBUG
2447                     if(H5DEBUG(T))
2448                         fprintf (H5DEBUG(T), "H5T: conversion function 0x%08lx "
2449                             "failed to free private data for %s (ignored)\n",
2450                             (unsigned long)(old_path->conv.u.app_func), old_path->name);
2451 #endif
2452                 } /* end if */
2453             } /* end if */
2454             else
2455                 if((old_path->conv.u.lib_func)(tmp_sid, tmp_did, &(old_path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
2456 #ifdef H5T_DEBUG
2457                     if(H5DEBUG(T))
2458                         fprintf (H5DEBUG(T), "H5T: conversion function 0x%08lx "
2459                             "failed to free private data for %s (ignored)\n",
2460                             (unsigned long)(old_path->conv.u.lib_func), old_path->name);
2461 #endif
2462                 } /* end if */
2463             (void)H5T_close_real(old_path->src);
2464             (void)H5T_close_real(old_path->dst);
2465             old_path = H5FL_FREE(H5T_path_t, old_path);
2466 
2467             /* Release temporary atoms */
2468             H5I_dec_ref(tmp_sid);
2469             H5I_dec_ref(tmp_did);
2470             tmp_sid = tmp_did = -1;
2471 
2472             /* We don't care about any failures during the freeing process */
2473             H5E_clear_stack(NULL);
2474         } /* end for */
2475     } /* end else */
2476 
2477 done:
2478     if(ret_value < 0) {
2479         if(new_path) {
2480             if(new_path->src)
2481                     (void)H5T_close_real(new_path->src);
2482             if(new_path->dst)
2483                     (void)H5T_close_real(new_path->dst);
2484                 new_path = H5FL_FREE(H5T_path_t, new_path);
2485         } /* end if */
2486         if(tmp_sid >= 0)
2487                 H5I_dec_ref(tmp_sid);
2488         if(tmp_did >= 0)
2489                 H5I_dec_ref(tmp_did);
2490     } /* end if */
2491 
2492     FUNC_LEAVE_NOAPI(ret_value)
2493 } /* end H5T__register() */
2494 
2495 
2496 /*-------------------------------------------------------------------------
2497  * Function:    H5Tregister
2498  *
2499  * Purpose:    Register a hard or soft conversion function for a data type
2500  *        conversion path.  The path is specified by the source and
2501  *        destination data types SRC_ID and DST_ID (for soft functions
2502  *        only the class of these types is important). If FUNC is a
2503  *        hard function then it replaces any previous path; if it's a
2504  *        soft function then it replaces all existing paths to which it
2505  *        applies and is used for any new path to which it applies as
2506  *        long as that path doesn't have a hard function.
2507  *
2508  * Return:    Non-negative on success/Negative on failure
2509  *
2510  * Programmer:    Robb Matzke
2511  *        Friday, January     9, 1998
2512  *
2513  *-------------------------------------------------------------------------
2514  */
2515 herr_t
H5Tregister(H5T_pers_t pers,const char * name,hid_t src_id,hid_t dst_id,H5T_conv_t func)2516 H5Tregister(H5T_pers_t pers, const char *name, hid_t src_id, hid_t dst_id,
2517     H5T_conv_t func)
2518 {
2519     H5T_t     *src;                  /*source data type descriptor    */
2520     H5T_t     *dst;                  /*destination data type desc     */
2521     H5T_conv_func_t conv_func;       /* Conversion function wrapper */
2522     herr_t    ret_value = SUCCEED;   /*return value                   */
2523 
2524     FUNC_ENTER_API(FAIL)
2525     H5TRACE5("e", "Te*siix", pers, name, src_id, dst_id, func);
2526 
2527     /* Check args */
2528     if(H5T_PERS_HARD != pers && H5T_PERS_SOFT != pers)
2529         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid function persistence")
2530     if(!name || !*name)
2531         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "conversion must have a name for debugging")
2532     if(NULL == (src = (H5T_t *)H5I_object_verify(src_id,H5I_DATATYPE)))
2533         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
2534     if(NULL == (dst = (H5T_t *)H5I_object_verify(dst_id,H5I_DATATYPE)))
2535         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
2536     if(!func)
2537         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no conversion function specified")
2538 
2539     /* Set up conversion function wrapper */
2540     conv_func.is_app = TRUE;
2541     conv_func.u.app_func = func;
2542 
2543     /* Go register the function */
2544     if(H5T__register(pers, name, src, dst, &conv_func) < 0)
2545         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't register conversion function")
2546 
2547 done:
2548     FUNC_LEAVE_API(ret_value)
2549 } /* end H5Tregister() */
2550 
2551 
2552 /*-------------------------------------------------------------------------
2553  * Function:   H5T__unregister
2554  *
2555  * Purpose:    Removes conversion paths that match the specified criteria.
2556  *        All arguments are optional. Missing arguments are wild cards.
2557  *        The special no-op path cannot be removed.
2558  *
2559  * Return:    Succeess:    non-negative
2560  *            Failure:    negative
2561  *
2562  * Programmer:    Robb Matzke
2563  *        Tuesday, January 13, 1998
2564  *
2565  *-------------------------------------------------------------------------
2566  */
2567 static herr_t
H5T__unregister(H5T_pers_t pers,const char * name,H5T_t * src,H5T_t * dst,H5T_conv_t func)2568 H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
2569     H5T_conv_t func)
2570 {
2571     H5T_path_t    *path = NULL;     /*conversion path             */
2572     H5T_soft_t    *soft = NULL;     /*soft conversion information */
2573     int           nprint = 0;       /*number of paths shut down   */
2574     int           i;                /*counter                     */
2575 
2576     FUNC_ENTER_STATIC_NOERR
2577 
2578     /* Remove matching entries from the soft list */
2579     if(H5T_PERS_DONTCARE == pers || H5T_PERS_SOFT == pers) {
2580         for(i = H5T_g.nsoft - 1; i >= 0; --i) {
2581             soft = H5T_g.soft + i;
2582             HDassert(soft);
2583             if(name && *name && HDstrcmp(name, soft->name))
2584                 continue;
2585             if(src && src->shared->type != soft->src)
2586                 continue;
2587             if(dst && dst->shared->type != soft->dst)
2588                 continue;
2589             if(func && func != soft->conv.u.app_func)
2590                 continue;
2591 
2592             HDmemmove(H5T_g.soft + i, H5T_g.soft + i + 1, (size_t)(H5T_g.nsoft - (i + 1)) * sizeof(H5T_soft_t));
2593             --H5T_g.nsoft;
2594         } /* end for */
2595     } /* end if */
2596 
2597     /* Remove matching conversion paths, except no-op path */
2598     for(i = H5T_g.npaths - 1; i > 0; --i) {
2599         path = H5T_g.path[i];
2600         HDassert(path);
2601 
2602         /* Not a match */
2603         if(((H5T_PERS_SOFT == pers && path->is_hard) ||
2604                     (H5T_PERS_HARD == pers && !path->is_hard)) ||
2605                 (name && *name && HDstrcmp(name, path->name)) ||
2606                 (src && H5T_cmp(src, path->src, FALSE)) ||
2607                 (dst && H5T_cmp(dst, path->dst, FALSE)) ||
2608                 (func && func != path->conv.u.app_func)) {
2609             /*
2610              * Notify all other functions to recalculate private data since some
2611              * functions might cache a list of conversion functions.  For
2612              * instance, the compound type converter caches a list of conversion
2613              * functions for the members, so removing a function should cause
2614              * the list to be recalculated to avoid the removed function.
2615              */
2616             path->cdata.recalc = TRUE;
2617         } /* end if */
2618         else {
2619             /* Remove from table */
2620             HDmemmove(H5T_g.path + i, H5T_g.path + i + 1, (size_t)(H5T_g.npaths - (i + 1)) * sizeof(H5T_path_t*));
2621             --H5T_g.npaths;
2622 
2623             /* Shut down path */
2624             H5T__print_stats(path, &nprint);
2625             path->cdata.command = H5T_CONV_FREE;
2626             if(path->conv.is_app) {
2627                 if((path->conv.u.app_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
2628 #ifdef H5T_DEBUG
2629                     if(H5DEBUG(T))
2630                         fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx failed "
2631                                 "to free private data for %s (ignored)\n",
2632                                 (unsigned long)(path->conv.u.app_func), path->name);
2633 #endif
2634                 } /* end if */
2635             } /* end if */
2636             else
2637                 if((path->conv.u.lib_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
2638 #ifdef H5T_DEBUG
2639                     if(H5DEBUG(T))
2640                         fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx failed "
2641                                 "to free private data for %s (ignored)\n",
2642                                 (unsigned long)(path->conv.u.lib_func), path->name);
2643 #endif
2644                 } /* end if */
2645             (void)H5T_close_real(path->src);
2646             (void)H5T_close_real(path->dst);
2647             path = H5FL_FREE(H5T_path_t, path);
2648             H5E_clear_stack(NULL); /*ignore all shutdown errors*/
2649         } /* end else */
2650     } /* end for */
2651 
2652     FUNC_LEAVE_NOAPI(SUCCEED)
2653 } /* end H5T__unregister() */
2654 
2655 
2656 /*-------------------------------------------------------------------------
2657  * Function:  H5Tunregister
2658  *
2659  * Purpose:   Removes conversion paths that match the specified criteria.
2660  *        All arguments are optional. Missing arguments are wild cards.
2661  *        The special no-op path cannot be removed.
2662  *
2663  * Return:    Succeess:    non-negative
2664  *
2665  *            Failure:    negative
2666  *
2667  * Programmer:    Robb Matzke
2668  *        Tuesday, January 13, 1998
2669  *
2670  *-------------------------------------------------------------------------
2671  */
2672 herr_t
H5Tunregister(H5T_pers_t pers,const char * name,hid_t src_id,hid_t dst_id,H5T_conv_t func)2673 H5Tunregister(H5T_pers_t pers, const char *name, hid_t src_id, hid_t dst_id,
2674     H5T_conv_t func)
2675 {
2676     H5T_t       *src = NULL, *dst = NULL;    /* Datatype descriptors */
2677     herr_t      ret_value = SUCCEED;         /* Return value */
2678 
2679     FUNC_ENTER_API(FAIL)
2680     H5TRACE5("e", "Te*siix", pers, name, src_id, dst_id, func);
2681 
2682     /* Check arguments */
2683     if(src_id > 0 && (NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE))))
2684         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src is not a data type")
2685     if(dst_id > 0 && (NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))))
2686         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst is not a data type")
2687 
2688     if(H5T__unregister(pers, name, src, dst, func) < 0)
2689         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDELETE, FAIL, "internal unregister function failed")
2690 
2691 done:
2692     FUNC_LEAVE_API(ret_value)
2693 } /* end H5Tunregister() */
2694 
2695 
2696 /*-------------------------------------------------------------------------
2697  * Function:  H5Tfind
2698  *
2699  * Purpose:   Finds a conversion function that can handle a conversion from
2700  *        type SRC_ID to type DST_ID.  The PCDATA argument is a pointer
2701  *        to a pointer to type conversion data which was created and
2702  *        initialized by the type conversion function of this path
2703  *        when the conversion function was installed on the path.
2704  *
2705  * Return:    Success:    A pointer to a suitable conversion function.
2706  *
2707  *            Failure:    NULL
2708  *
2709  * Programmer:    Robb Matzke
2710  *        Tuesday, January 13, 1998
2711  *
2712  *-------------------------------------------------------------------------
2713  */
2714 H5T_conv_t
H5Tfind(hid_t src_id,hid_t dst_id,H5T_cdata_t ** pcdata)2715 H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata)
2716 {
2717     H5T_t         *src, *dst;
2718     H5T_path_t    *path;
2719     H5T_conv_t    ret_value;      /* Return value */
2720 
2721     FUNC_ENTER_API(NULL)
2722     H5TRACE3("x", "ii**x", src_id, dst_id, pcdata);
2723 
2724     /* Check args */
2725     if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) ||
2726             NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE)))
2727         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type")
2728     if(!pcdata)
2729         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no address to receive cdata pointer")
2730 
2731     /* Find it */
2732     if(NULL == (path = H5T_path_find(src, dst)))
2733         HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "conversion function not found")
2734 
2735     if(pcdata)
2736         *pcdata = &(path->cdata);
2737 
2738     /* Set return value */
2739     ret_value = path->conv.u.app_func;
2740 
2741 done:
2742     FUNC_LEAVE_API(ret_value)
2743 } /* end H5Tfind() */
2744 
2745 
2746 /*-------------------------------------------------------------------------
2747  * Function:  H5Tcompiler_conv
2748  *
2749  * Purpose:   Finds out whether the library's conversion function from
2750  *            type src_id to type dst_id is a compiler (hard) conversion.
2751  *            A hard conversion uses compiler's casting; a soft conversion
2752  *            uses the library's own conversion function.
2753  *
2754  * Return:    TRUE:           hard conversion.
2755  *            FALSE:          soft conversion.
2756  *            FAIL:           failed.
2757  *
2758  * Programmer:    Raymond Lu
2759  *        Friday, Sept 2, 2005
2760  *
2761  *-------------------------------------------------------------------------
2762  */
2763 htri_t
H5Tcompiler_conv(hid_t src_id,hid_t dst_id)2764 H5Tcompiler_conv(hid_t src_id, hid_t dst_id)
2765 {
2766     H5T_t     *src, *dst;
2767     htri_t    ret_value;      /* Return value */
2768 
2769     FUNC_ENTER_API(FAIL)
2770     H5TRACE2("t", "ii", src_id, dst_id);
2771 
2772     /* Check args */
2773     if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) ||
2774             NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE)))
2775         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
2776 
2777     /* Find it */
2778     if((ret_value = H5T__compiler_conv(src, dst)) < 0)
2779         HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "conversion function not found")
2780 
2781 done:
2782     FUNC_LEAVE_API(ret_value)
2783 } /* end H5Tcompiler_conv() */
2784 
2785 
2786 /*-------------------------------------------------------------------------
2787  * Function:  H5Tconvert
2788  *
2789  * Purpose:   Convert NELMTS elements from type SRC_ID to type DST_ID.  The
2790  *        source elements are packed in BUF and on return the
2791  *        destination will be packed in BUF.  That is, the conversion
2792  *        is performed in place.  The optional background buffer is an
2793  *        array of NELMTS values of destination type which are merged
2794  *        with the converted values to fill in cracks (for instance,
2795  *        BACKGROUND might be an array of structs with the `a' and `b'
2796  *        fields already initialized and the conversion of BUF supplies
2797  *        the `c' and `d' field values).  The PLIST_ID a dataset transfer
2798  *        property list which is passed to the conversion functions.  (It's
2799  *        currently only used to pass along the VL datatype custom allocation
2800  *        information -QAK 7/1/99)
2801  *
2802  * Return:    Non-negative on success/Negative on failure
2803  *
2804  * Programmer:    Robb Matzke
2805  *              Wednesday, June 10, 1998
2806  *
2807  *-------------------------------------------------------------------------
2808  */
2809 herr_t
H5Tconvert(hid_t src_id,hid_t dst_id,size_t nelmts,void * buf,void * background,hid_t dxpl_id)2810 H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf,
2811         void *background, hid_t dxpl_id)
2812 {
2813     H5T_path_t    *tpath;                 /* type conversion info    */
2814     H5T_t         *src, *dst;             /* unatomized types        */
2815     herr_t        ret_value = SUCCEED;    /* Return value            */
2816 
2817     FUNC_ENTER_API(FAIL)
2818     H5TRACE6("e", "iiz*x*xi", src_id, dst_id, nelmts, buf, background, dxpl_id);
2819 
2820     /* Check args */
2821     if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) ||
2822             NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE)))
2823         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
2824     if(H5P_DEFAULT == dxpl_id)
2825         dxpl_id = H5P_DATASET_XFER_DEFAULT;
2826     else
2827         if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
2828             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset transfer property list")
2829 
2830     /* Set DXPL for operation */
2831     H5CX_set_dxpl(dxpl_id);
2832 
2833     /* Find the conversion function */
2834     if(NULL == (tpath = H5T_path_find(src, dst)))
2835         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types")
2836 
2837     if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, buf, background) < 0)
2838         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed")
2839 
2840 done:
2841     FUNC_LEAVE_API(ret_value)
2842 } /* end H5Tconvert() */
2843 
2844 
2845 /*-------------------------------------------------------------------------
2846  * Function:  H5Tencode
2847  *
2848  * Purpose:   Given an datatype ID, converts the object description into
2849  *            binary in a buffer.
2850  *
2851  * Return:    Success:    non-negative
2852  *
2853  *            Failure:    negative
2854  *
2855  * Programmer:    Raymond Lu
2856  *              July 14, 2004
2857  *
2858  *-------------------------------------------------------------------------
2859  */
2860 herr_t
H5Tencode(hid_t obj_id,void * buf,size_t * nalloc)2861 H5Tencode(hid_t obj_id, void *buf, size_t *nalloc)
2862 {
2863     H5T_t       *dtype;
2864     herr_t      ret_value = SUCCEED;
2865 
2866     FUNC_ENTER_API(FAIL)
2867     H5TRACE3("e", "i*x*z", obj_id, buf, nalloc);
2868 
2869     /* Check argument and retrieve object */
2870     if(NULL == (dtype = (H5T_t *)H5I_object_verify(obj_id, H5I_DATATYPE)))
2871         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
2872     if(nalloc == NULL)
2873         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL pointer for buffer size")
2874 
2875     /* Go encode the datatype */
2876     if(H5T_encode(dtype, (unsigned char *)buf, nalloc) < 0)
2877         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
2878 
2879 done:
2880     FUNC_LEAVE_API(ret_value)
2881 } /* end H5Tencode() */
2882 
2883 
2884 /*-------------------------------------------------------------------------
2885  * Function:  H5Tdecode
2886  *
2887  * Purpose:   Decode a binary object description and return a new object
2888  *            handle.
2889  *
2890  * Return:    Success:    datatype ID(non-negative)
2891  *
2892  *            Failure:    negative
2893  *
2894  * Programmer:    Raymond Lu
2895  *              July 14, 2004
2896  *
2897  * Modification:Raymond Lu
2898  *              17 February 2011
2899  *              I changed the value for the APP_REF parameter of H5I_register
2900  *              from FALSE to TRUE.
2901  *-------------------------------------------------------------------------
2902  */
2903 hid_t
H5Tdecode(const void * buf)2904 H5Tdecode(const void *buf)
2905 {
2906     H5T_t       *dt;
2907     hid_t       ret_value;      /* Return value */
2908 
2909     FUNC_ENTER_API(FAIL)
2910     H5TRACE1("i", "*x", buf);
2911 
2912     /* Check args */
2913     if(buf == NULL)
2914         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "empty buffer")
2915 
2916     /* Create datatype by decoding buffer
2917      * There is no way to get the size of the buffer, so we pass in
2918      * SIZE_MAX and assume the caller knows what they are doing.
2919      * Really fixing this will require an H5Tdecode2() call that
2920      * takes a size parameter.
2921      */
2922     if(NULL == (dt = H5T_decode(SIZE_MAX, (const unsigned char *)buf)))
2923         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "can't decode object")
2924 
2925     /* Register the type and return the ID */
2926     if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
2927         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type")
2928 
2929 done:
2930     FUNC_LEAVE_API(ret_value)
2931 } /* end H5Tdecode() */
2932 
2933 /*-------------------------------------------------------------------------
2934  * API functions are above; library-private functions are below...
2935  *-------------------------------------------------------------------------
2936  */
2937 
2938 
2939 /*-------------------------------------------------------------------------
2940  * Function:  H5T_encode
2941  *
2942  * Purpose:   Private function for H5Tencode.  Converts an object
2943  *            description into binary in a buffer.
2944  *
2945  * Return:    Success:    non-negative
2946  *
2947  *            Failure:    negative
2948  *
2949  * Programmer:    Raymond Lu
2950  *              July 14, 2004
2951  *
2952  *-------------------------------------------------------------------------
2953  */
2954 herr_t
H5T_encode(H5T_t * obj,unsigned char * buf,size_t * nalloc)2955 H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc)
2956 {
2957     size_t      buf_size;               /* Encoded size of datatype */
2958     H5F_t       *f = NULL;              /* Fake file structure*/
2959     herr_t      ret_value = SUCCEED;
2960 
2961     FUNC_ENTER_NOAPI_NOINIT
2962 
2963     /* Allocate "fake" file structure */
2964     if(NULL == (f = H5F_fake_alloc((uint8_t)0, H5P_FILE_ACCESS_DEFAULT)))
2965         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate fake file struct")
2966 
2967     /* Find out the size of buffer needed */
2968     if((buf_size = H5O_msg_raw_size(f, H5O_DTYPE_ID, TRUE, obj)) == 0)
2969         HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "can't find datatype size")
2970 
2971     /* Don't encode if buffer size isn't big enough or buffer is empty */
2972     if(!buf || *nalloc < (buf_size + 1 + 1))
2973         *nalloc = buf_size + 1 + 1;
2974     else {
2975         /* Encode the type of the information */
2976         *buf++ = H5O_DTYPE_ID;
2977 
2978         /* Encode the version of the dataspace information */
2979         *buf++ = H5T_ENCODE_VERSION;
2980 
2981         /* Encode into user's buffer */
2982         if(H5O_msg_encode(f, H5O_DTYPE_ID, TRUE, buf, obj) < 0)
2983             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode object")
2984     } /* end else */
2985 
2986 done:
2987     /* Release fake file structure */
2988     if(f && H5F_fake_free(f) < 0)
2989         HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release fake file struct")
2990 
2991     FUNC_LEAVE_NOAPI(ret_value)
2992 } /* end H5T_encode() */
2993 
2994 
2995 /*-------------------------------------------------------------------------
2996  * Function:  H5T_decode
2997  *
2998  * Purpose:   Private function for H5Tdecode.  Reconstructs a binary
2999  *            description of datatype and returns a new object handle.
3000  *
3001  * Return:    Success:    datatype ID(non-negative)
3002  *
3003  *            Failure:    negative
3004  *
3005  * Programmer:    Raymond Lu
3006  *              July 14, 2004
3007  *
3008  *-------------------------------------------------------------------------
3009  */
3010 H5T_t *
H5T_decode(size_t buf_size,const unsigned char * buf)3011 H5T_decode(size_t buf_size, const unsigned char *buf)
3012 {
3013     H5F_t *f = NULL;            /* Fake file structure*/
3014     H5T_t *ret_value = NULL;    /* Return value */
3015 
3016     FUNC_ENTER_NOAPI_NOINIT
3017 
3018     /* Allocate "fake" file structure */
3019     if(NULL == (f = H5F_fake_alloc((uint8_t)0, H5P_FILE_ACCESS_DEFAULT)))
3020         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "can't allocate fake file struct")
3021 
3022     /* Decode the type of the information */
3023     if(*buf++ != H5O_DTYPE_ID)
3024         HGOTO_ERROR(H5E_DATATYPE, H5E_BADMESG, NULL, "not an encoded datatype")
3025 
3026     /* Decode the version of the datatype information */
3027     if(*buf++ != H5T_ENCODE_VERSION)
3028         HGOTO_ERROR(H5E_DATATYPE, H5E_VERSION, NULL, "unknown version of encoded datatype")
3029 
3030     /* Decode the serialized datatype message */
3031     if(NULL == (ret_value = (H5T_t *)H5O_msg_decode(f, NULL, H5O_DTYPE_ID, buf_size, buf)))
3032         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object")
3033 
3034     /* Mark datatype as being in memory now */
3035     if(H5T_set_loc(ret_value, NULL, H5T_LOC_MEMORY) < 0)
3036         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
3037 
3038 done:
3039     /* Release fake file structure */
3040     if(f && H5F_fake_free(f) < 0)
3041         HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, NULL, "unable to release fake file struct")
3042 
3043     FUNC_LEAVE_NOAPI(ret_value)
3044 } /* end H5T_decode() */
3045 
3046 
3047 /*-------------------------------------------------------------------------
3048  * Function:  H5T__create
3049  *
3050  * Purpose:   Creates a new data type and initializes it to reasonable
3051  *            values.     The new data type is SIZE bytes and an instance of
3052  *            the class TYPE.
3053  *
3054  * Return:    Success:    Pointer to the new type.
3055  *
3056  *            Failure:    NULL
3057  *
3058  * Programmer:    Robb Matzke
3059  *        Friday, December  5, 1997
3060  *
3061  * Modifications:
3062  *              Raymond Lu
3063  *              19 May 2011
3064  *              We support fixed size or variable-length string now.
3065  *-------------------------------------------------------------------------
3066  */
3067 H5T_t *
H5T__create(H5T_class_t type,size_t size)3068 H5T__create(H5T_class_t type, size_t size)
3069 {
3070     H5T_t  *dt = NULL;
3071     H5T_t  *ret_value = NULL;
3072 
3073     FUNC_ENTER_PACKAGE
3074 
3075     switch(type) {
3076         case H5T_INTEGER:
3077         case H5T_FLOAT:
3078         case H5T_TIME:
3079         case H5T_STRING:
3080             {
3081                 H5T_t *origin_dt = NULL;
3082 
3083                 if(NULL == (origin_dt = (H5T_t *)H5I_object(H5T_C_S1)))
3084                     HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "can't get structure for string type")
3085 
3086                 /* Copy the default string datatype */
3087                 if(NULL == (dt = H5T_copy(origin_dt, H5T_COPY_TRANSIENT)))
3088                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy");
3089 
3090                 /* Modify the datatype */
3091                 if(H5T__set_size(dt, size) < 0)
3092                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to set size for string type")
3093             }
3094             break;
3095 
3096         case H5T_BITFIELD:
3097             HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "type class is not appropriate - use H5Tcopy()")
3098 
3099         case H5T_OPAQUE:
3100         case H5T_COMPOUND:
3101             if(NULL == (dt = H5T__alloc()))
3102                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
3103             dt->shared->type = type;
3104 
3105             if(type == H5T_COMPOUND) {
3106                 dt->shared->u.compnd.packed=FALSE;       /* Start out unpacked */
3107                 dt->shared->u.compnd.memb_size=0;
3108             } /* end if */
3109             else if(type == H5T_OPAQUE)
3110                 /* Initialize the tag in case it's not set later.  A null tag will
3111                  * cause problems for later operations. */
3112                 dt->shared->u.opaque.tag = H5MM_strdup("");
3113             break;
3114 
3115         case H5T_ENUM:
3116             {
3117                 hid_t  subtype;
3118                 H5T_t  *sub_t_obj;
3119 
3120                 if(sizeof(char) == size)
3121                     subtype = H5T_NATIVE_SCHAR_g;
3122                 else if(sizeof(short) == size)
3123                     subtype = H5T_NATIVE_SHORT_g;
3124                 else if(sizeof(int) == size)
3125                     subtype = H5T_NATIVE_INT_g;
3126                 else if(sizeof(long) == size)
3127                     subtype = H5T_NATIVE_LONG_g;
3128 #if H5_SIZEOF_LONG != H5_SIZEOF_LONG_LONG
3129                 else if(sizeof(long long) == size)
3130                     subtype = H5T_NATIVE_LLONG_g;
3131 #endif /* H5_SIZEOF_LONG != H5_SIZEOF_LONG_LONG */
3132                 else
3133                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no applicable native integer type")
3134                 if(NULL == (dt = H5T__alloc()))
3135                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
3136                 dt->shared->type = type;
3137                 if(NULL == (sub_t_obj = (H5T_t *)H5I_object(subtype)))
3138                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, NULL, "unable to get datatype object")
3139                 if(NULL == (dt->shared->parent = H5T_copy(sub_t_obj, H5T_COPY_ALL)))
3140                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy base datatype")
3141             }
3142             break;
3143 
3144         case H5T_VLEN:  /* Variable length datatype */
3145             HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "base type required - use H5Tvlen_create()")
3146 
3147         case H5T_ARRAY:  /* Array datatype */
3148             HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "base type required - use H5Tarray_create2()")
3149 
3150         case H5T_NO_CLASS:
3151         case H5T_REFERENCE:
3152         case H5T_NCLASSES:
3153         default:
3154             HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, NULL, "unknown data type class")
3155     } /* end switch */
3156 
3157     /* Set the size except VL string */
3158     if(H5T_STRING != type || H5T_VARIABLE != size)
3159         dt->shared->size = size;
3160 
3161     /* Set return value */
3162     ret_value = dt;
3163 
3164 done:
3165     if(NULL == ret_value) {
3166         if(dt) {
3167             dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
3168             dt = H5FL_FREE(H5T_t, dt);
3169         } /* end if */
3170     } /* end if */
3171 
3172     FUNC_LEAVE_NOAPI(ret_value)
3173 } /* end H5T__create() */
3174 
3175 
3176 /*-------------------------------------------------------------------------
3177  * Function:  H5T_copy
3178  *
3179  * Purpose:   Copies datatype OLD_DT.     The resulting data type is not
3180  *            locked and is a transient type.
3181  *
3182  * Return:    Success:    Pointer to a new copy of the OLD_DT argument.
3183  *
3184  *            Failure:    NULL
3185  *
3186  * Programmer:    Robb Matzke
3187  *        Thursday, December  4, 1997
3188  *
3189  * Modifications:
3190  *
3191  *     Robb Matzke, 4 Jun 1998
3192  *    Added the METHOD argument.  If it's H5T_COPY_TRANSIENT then the
3193  *    result will be an unlocked transient type.  Otherwise if it's
3194  *    H5T_COPY_ALL then the result is a named type if the original is a
3195  *    named type, but the result is not opened.  Finally, if it's
3196  *    H5T_COPY_REOPEN and the original type is a named type then the result
3197  *    is a named type and the type object header is opened again.  The
3198  *    H5T_COPY_REOPEN method is used when returning a named type to the
3199  *    application.
3200  *
3201  *     Robb Matzke, 22 Dec 1998
3202  *    Now able to copy enumeration data types.
3203  *
3204  *      Robb Matzke, 20 May 1999
3205  *    Now able to copy opaque types.
3206  *
3207  *      Pedro Vicente, <pvn@ncsa.uiuc.edu> 21 Sep 2002
3208  *      Added a deep copy of the symbol table entry
3209  *
3210  *-------------------------------------------------------------------------
3211  */
3212 H5T_t *
H5T_copy(H5T_t * old_dt,H5T_copy_t method)3213 H5T_copy(H5T_t *old_dt, H5T_copy_t method)
3214 {
3215     H5T_t           *new_dt = NULL, *tmp = NULL;
3216     H5T_shared_t    *reopened_fo = NULL;
3217     unsigned        i;
3218     char            *s;
3219     H5T_t           *ret_value = NULL;    /* Return value */
3220 
3221     FUNC_ENTER_NOAPI(NULL)
3222 
3223     /* check args */
3224     HDassert(old_dt);
3225 
3226     /* Allocate space */
3227     if(NULL == (new_dt = H5FL_MALLOC(H5T_t)))
3228         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
3229     if(NULL == (new_dt->shared = H5FL_MALLOC(H5T_shared_t)))
3230         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
3231 
3232     /* Copy shared information (entry information is copied last) */
3233     *(new_dt->shared) = *(old_dt->shared);
3234 
3235     /* Check what sort of copy we are making */
3236     switch (method) {
3237         case H5T_COPY_TRANSIENT:
3238             /*
3239              * Return an unlocked transient type.
3240              */
3241             new_dt->shared->state = H5T_STATE_TRANSIENT;
3242             break;
3243 
3244         case H5T_COPY_ALL:
3245             /*
3246              * Return a transient type (locked or unlocked) or an unopened named
3247              * type.  Immutable transient types are degraded to read-only.
3248              */
3249             if(H5T_STATE_OPEN==old_dt->shared->state)
3250                 new_dt->shared->state = H5T_STATE_NAMED;
3251             else if(H5T_STATE_IMMUTABLE==old_dt->shared->state)
3252                 new_dt->shared->state = H5T_STATE_RDONLY;
3253             break;
3254 
3255         case H5T_COPY_REOPEN:
3256             /*
3257              * Return a transient type (locked or unlocked) or an opened named
3258              * type.  Immutable transient types are degraded to read-only.
3259              */
3260             if(old_dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
3261                 /* Check if the object is already open */
3262                 if(NULL == (reopened_fo = (H5T_shared_t *)H5FO_opened(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr))) {
3263                     /* Clear any errors from H5FO_opened() */
3264                     H5E_clear_stack(NULL);
3265 
3266                     /* Open named datatype again */
3267                     if(H5O_open(&old_dt->oloc) < 0)
3268                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reopen named data type");
3269 
3270                     /* Insert opened named datatype into opened object list for the file */
3271                     if(H5FO_insert(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr, new_dt->shared, FALSE)<0)
3272                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects")
3273 
3274                     /* Increment object count for the object in the top file */
3275                     if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
3276                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
3277 
3278                     new_dt->shared->fo_count = 1;
3279                 } /* end if */
3280                 else {
3281                     /* The object is already open.  Free the H5T_shared_t struct
3282                      * we had been using and use the one that already exists.
3283                      * Not terribly efficient. */
3284                     new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
3285                     new_dt->shared = reopened_fo;
3286 
3287                     reopened_fo->fo_count++;
3288 
3289                     /* Check if the object has been opened through the top file yet */
3290                     if(H5FO_top_count(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) == 0) {
3291                         /* Open the object through this top file */
3292                         if(H5O_open(&old_dt->oloc) < 0)
3293                             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
3294                     } /* end if */
3295 
3296                     /* Increment object count for the object in the top file */
3297                     if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
3298                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
3299                 } /* end else */
3300                 new_dt->shared->state = H5T_STATE_OPEN;
3301             }
3302             else if(H5T_STATE_IMMUTABLE == old_dt->shared->state) {
3303                 new_dt->shared->state = H5T_STATE_RDONLY;
3304             }
3305             break;
3306         default:
3307             HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid copy method type")
3308     } /* end switch */
3309 
3310     /* Update fields in the new struct, if we aren't sharing an already opened
3311      * committed datatype */
3312     if(!reopened_fo) {
3313         /* Copy parent information */
3314         if(old_dt->shared->parent)
3315             new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method);
3316 
3317         switch(new_dt->shared->type) {
3318             case H5T_COMPOUND:
3319                 {
3320                     ssize_t accum_change = 0; /* Amount of change in the offset of the fields */
3321 
3322                     /*
3323                     * Copy all member fields to new type, then overwrite the
3324                     * name and type fields of each new member with copied values.
3325                     * That is, H5T_copy() is a deep copy.
3326                     */
3327                     /* Only malloc if space has been allocated for members - NAF */
3328                     if(new_dt->shared->u.compnd.nalloc > 0) {
3329                         new_dt->shared->u.compnd.memb =
3330                                 (H5T_cmemb_t *)H5MM_malloc(new_dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t));
3331                         if (NULL == new_dt->shared->u.compnd.memb)
3332                             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
3333 
3334                         HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
3335                                 new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
3336                     } /* end if */
3337 
3338                     for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) {
3339                         unsigned    j;
3340                         int         old_match;
3341 
3342                         s = new_dt->shared->u.compnd.memb[i].name;
3343                         new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s);
3344                         tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method);
3345                         new_dt->shared->u.compnd.memb[i].type = tmp;
3346                         HDassert(tmp != NULL);
3347 
3348                         /* Range check against compound member's offset */
3349                         if ((accum_change < 0) && ((ssize_t) new_dt->shared->u.compnd.memb[i].offset < accum_change))
3350                             HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, NULL, "invalid field size in datatype");
3351 
3352                         /* Apply the accumulated size change to the offset of the field */
3353                         new_dt->shared->u.compnd.memb[i].offset += (size_t) accum_change;
3354 
3355                         if(old_dt->shared->u.compnd.sorted != H5T_SORT_VALUE) {
3356                             for(old_match = -1, j = 0; j < old_dt->shared->u.compnd.nmembs; j++) {
3357                                 if(!HDstrcmp(new_dt->shared->u.compnd.memb[i].name, old_dt->shared->u.compnd.memb[j].name)) {
3358                                     old_match = (int) j;
3359                                     break;
3360                                 } /* end if */
3361                             } /* end for */
3362 
3363                             /* check if we couldn't find a match */
3364                             if(old_match < 0)
3365                                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted");
3366                         } /* end if */
3367                         else
3368                             old_match = (int) i;
3369 
3370                         /* If the field changed size, add that change to the accumulated size change */
3371                         if(new_dt->shared->u.compnd.memb[i].type->shared->size != old_dt->shared->u.compnd.memb[old_match].type->shared->size) {
3372                             /* Adjust the size of the member */
3373                             new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/old_dt->shared->u.compnd.memb[old_match].type->shared->size;
3374 
3375                             accum_change += (ssize_t) (new_dt->shared->u.compnd.memb[i].type->shared->size - old_dt->shared->u.compnd.memb[old_match].type->shared->size);
3376                         } /* end if */
3377                     } /* end for */
3378 
3379                     /* Range check against datatype size */
3380                     if ((accum_change < 0) && ((ssize_t) new_dt->shared->size < accum_change))
3381                         HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, NULL, "invalid field size in datatype");
3382 
3383                     /* Apply the accumulated size change to the size of the compound struct */
3384                     new_dt->shared->size += (size_t) accum_change;
3385                 }
3386                 break;
3387 
3388             case H5T_ENUM:
3389                 /*
3390                 * Copy all member fields to new type, then overwrite the name fields
3391                 * of each new member with copied values. That is, H5T_copy() is a
3392                 * deep copy.
3393                 */
3394                 new_dt->shared->u.enumer.name =
3395                         (char **)H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char*));
3396                 new_dt->shared->u.enumer.value =
3397                         (uint8_t *)H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size);
3398                 if(NULL == new_dt->shared->u.enumer.value)
3399                     HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
3400                 HDmemcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
3401                         new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
3402                 for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
3403                     s = old_dt->shared->u.enumer.name[i];
3404                     new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s);
3405                 } /* end for */
3406                 break;
3407 
3408             case H5T_VLEN:
3409             case H5T_REFERENCE:
3410                 if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) {
3411                     /* H5T_copy converts any type into a memory type */
3412                     if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0)
3413                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location");
3414                 } /* end if */
3415                 break;
3416 
3417             case H5T_OPAQUE:
3418                 /*
3419                 * Copy the tag name.
3420                 */
3421                 new_dt->shared->u.opaque.tag = H5MM_xstrdup(new_dt->shared->u.opaque.tag);
3422                 break;
3423 
3424             case H5T_ARRAY:
3425                 /* Re-compute the array's size, in case it's base type changed size */
3426                 new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size;
3427                 break;
3428 
3429             case H5T_NO_CLASS:
3430             case H5T_INTEGER:
3431             case H5T_FLOAT:
3432             case H5T_TIME:
3433             case H5T_STRING:
3434             case H5T_BITFIELD:
3435             case H5T_NCLASSES:
3436             default:
3437                 break;
3438         } /* end switch */
3439     } /* end if */
3440 
3441     /* Set the cached location & name path if the original type was a named
3442      * type and the new type is also named.
3443      */
3444     if(H5O_loc_reset(&new_dt->oloc) < 0)
3445         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to initialize location")
3446     if(H5G_name_reset(&new_dt->path) < 0)
3447         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reset path")
3448 
3449     if(new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
3450         if(H5O_loc_copy(&(new_dt->oloc), &(old_dt->oloc), H5_COPY_DEEP) < 0)
3451             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
3452         if(H5G_name_copy(&(new_dt->path), &(old_dt->path), H5_COPY_DEEP) < 0)
3453             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to copy path")
3454     } /* end if */
3455 
3456     /* Copy shared location information if the new type is named or if it is
3457      * shared in the heap.
3458      */
3459     if((old_dt->sh_loc.type == H5O_SHARE_TYPE_SOHM || old_dt->sh_loc.type == H5O_SHARE_TYPE_HERE) ||
3460             new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
3461         if(H5O_set_shared(&(new_dt->sh_loc), &(old_dt->sh_loc)) < 0)
3462             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy shared information")
3463     } /* end if */
3464     else
3465         /* Reset shared component info */
3466         H5O_msg_reset_share(H5O_DTYPE_ID, new_dt);
3467 
3468     /* Set return value */
3469     ret_value = new_dt;
3470 
3471 done:
3472     if(ret_value == NULL) {
3473         if(new_dt) {
3474             if(new_dt->shared)
3475                 new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
3476             new_dt = H5FL_FREE(H5T_t, new_dt);
3477         } /* end if */
3478     } /* end if */
3479 
3480     FUNC_LEAVE_NOAPI(ret_value)
3481 } /* end H5T_copy() */
3482 
3483 
3484 /*-------------------------------------------------------------------------
3485  * Function:  H5T_lock
3486  *
3487  * Purpose:   Lock a transient data type making it read-only.  If IMMUTABLE
3488  *        is set then the type cannot be closed except when the library
3489  *        itself closes.
3490  *
3491  *        This function is a no-op if the type is not transient or if
3492  *        the type is already read-only or immutable.
3493  *
3494  * Return:    Non-negative on success/Negative on failure
3495  *
3496  * Programmer:    Robb Matzke
3497  *              Thursday, June  4, 1998
3498  *-------------------------------------------------------------------------
3499  */
3500 herr_t
H5T_lock(H5T_t * dt,hbool_t immutable)3501 H5T_lock (H5T_t *dt, hbool_t immutable)
3502 {
3503     herr_t ret_value=SUCCEED;   /* Return value */
3504 
3505     FUNC_ENTER_NOAPI(FAIL)
3506 
3507     HDassert (dt);
3508 
3509     switch (dt->shared->state) {
3510         case H5T_STATE_TRANSIENT:
3511             dt->shared->state = immutable ? H5T_STATE_IMMUTABLE : H5T_STATE_RDONLY;
3512             break;
3513         case H5T_STATE_RDONLY:
3514             if (immutable) dt->shared->state = H5T_STATE_IMMUTABLE;
3515             break;
3516         case H5T_STATE_IMMUTABLE:
3517         case H5T_STATE_NAMED:
3518         case H5T_STATE_OPEN:
3519             /*void*/
3520             break;
3521         default:
3522             HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid datatype state")
3523     }
3524 
3525 done:
3526     FUNC_LEAVE_NOAPI(ret_value)
3527 }
3528 
3529 
3530 /*-------------------------------------------------------------------------
3531  * Function:  H5T__alloc
3532  *
3533  * Purpose:   Allocates a new H5T_t structure, initializing it correctly.
3534  *
3535  * Return:    Pointer to new H5T_t on success/NULL on failure
3536  *
3537  * Programmer:    Quincey Koziol
3538  *        Monday, August 29, 2005
3539  *
3540  *-------------------------------------------------------------------------
3541  */
3542 H5T_t *
H5T__alloc(void)3543 H5T__alloc(void)
3544 {
3545     H5T_t *dt = NULL;           /* Pointer to datatype allocated */
3546     H5T_t *ret_value = NULL;    /* Return value */
3547 
3548     FUNC_ENTER_PACKAGE
3549 
3550     /* Allocate & initialize datatype wrapper info */
3551     if(NULL == (dt = H5FL_CALLOC(H5T_t)))
3552         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
3553     H5O_loc_reset(&(dt->oloc));
3554     H5G_name_reset(&(dt->path));
3555     H5O_msg_reset_share(H5O_DTYPE_ID, dt);
3556 
3557     /* Allocate & initialize shared datatype structure */
3558     if(NULL == (dt->shared = H5FL_CALLOC(H5T_shared_t)))
3559         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
3560     dt->shared->version = H5O_DTYPE_VERSION_1;
3561 
3562     /* Assign return value */
3563     ret_value = dt;
3564 
3565 done:
3566     if(ret_value == NULL)
3567         if(dt) {
3568             if(dt->shared)
3569                 dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
3570             dt = H5FL_FREE(H5T_t, dt);
3571         } /* end if */
3572 
3573     FUNC_LEAVE_NOAPI(ret_value)
3574 } /* end H5T__alloc() */
3575 
3576 
3577 /*-------------------------------------------------------------------------
3578  * Function:  H5T__free
3579  *
3580  * Purpose:   Frees all memory associated with a datatype, but does not
3581  *            free the H5T_t or H5T_shared_t structures (which should
3582  *            be done in H5T_close / H5T_close_real).
3583  *
3584  * Return:    Non-negative on success/Negative on failure
3585  *
3586  * Programmer:    Quincey Koziol
3587  *        Monday, January  6, 2003
3588  *
3589  *-------------------------------------------------------------------------
3590  */
3591 herr_t
H5T__free(H5T_t * dt)3592 H5T__free(H5T_t *dt)
3593 {
3594     unsigned    i;
3595     herr_t      ret_value = SUCCEED;       /* Return value */
3596 
3597     FUNC_ENTER_PACKAGE
3598 
3599     HDassert(dt && dt->shared);
3600 
3601     /* Free the ID to name info */
3602     H5G_name_free(&(dt->path));
3603 
3604     /*
3605      * Don't free locked datatypes.
3606      */
3607     if(H5T_STATE_IMMUTABLE==dt->shared->state)
3608         HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close immutable datatype")
3609 
3610     /* Close the datatype */
3611     switch(dt->shared->type) {
3612         case H5T_COMPOUND:
3613             for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
3614                 dt->shared->u.compnd.memb[i].name = (char *)H5MM_xfree(dt->shared->u.compnd.memb[i].name);
3615                 (void)H5T_close_real(dt->shared->u.compnd.memb[i].type);
3616             } /* end for */
3617             dt->shared->u.compnd.memb = (H5T_cmemb_t *)H5MM_xfree(dt->shared->u.compnd.memb);
3618             dt->shared->u.compnd.nmembs = 0;
3619             break;
3620 
3621         case H5T_ENUM:
3622             for(i = 0; i < dt->shared->u.enumer.nmembs; i++)
3623                 dt->shared->u.enumer.name[i] = (char *)H5MM_xfree(dt->shared->u.enumer.name[i]);
3624             dt->shared->u.enumer.name = (char **)H5MM_xfree(dt->shared->u.enumer.name);
3625             dt->shared->u.enumer.value = (uint8_t *)H5MM_xfree(dt->shared->u.enumer.value);
3626             dt->shared->u.enumer.nmembs = 0;
3627             break;
3628 
3629         case H5T_OPAQUE:
3630             dt->shared->u.opaque.tag = (char *)H5MM_xfree(dt->shared->u.opaque.tag);
3631             break;
3632 
3633         case H5T_NO_CLASS:
3634         case H5T_INTEGER:
3635         case H5T_FLOAT:
3636         case H5T_TIME:
3637         case H5T_STRING:
3638         case H5T_BITFIELD:
3639         case H5T_REFERENCE:
3640         case H5T_VLEN:
3641         case H5T_ARRAY:
3642         case H5T_NCLASSES:
3643         default:
3644             break;
3645     } /* end switch */
3646     dt->shared->type = H5T_NO_CLASS;
3647 
3648     /* Close the parent */
3649     HDassert(dt->shared->parent != dt);
3650     if(dt->shared->parent && H5T_close_real(dt->shared->parent) < 0)
3651         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close parent data type")
3652     dt->shared->parent = NULL;
3653 
3654 done:
3655     FUNC_LEAVE_NOAPI(ret_value)
3656 } /* end H5T__free() */
3657 
3658 
3659 /*-------------------------------------------------------------------------
3660  * Function:  H5T_close_real
3661  *
3662  * Purpose:   Frees a datatype and all associated memory.
3663  *
3664  * Hote:      Does _not_ deal with open hamed datatypes, etc.
3665  *
3666  * Return:    Non-negative on success/Negative on failure
3667  *
3668  * Programmer: Quincey Koziol
3669  *             Monday, February 12, 2018
3670  *
3671  *-------------------------------------------------------------------------
3672  */
3673 herr_t
H5T_close_real(H5T_t * dt)3674 H5T_close_real(H5T_t *dt)
3675 {
3676     herr_t      ret_value = SUCCEED;       /* Return value */
3677 
3678     FUNC_ENTER_NOAPI(FAIL)
3679 
3680     /* Sanity check */
3681     HDassert(dt && dt->shared);
3682 
3683     /* Clean up resources, depending on shared state */
3684     if(dt->shared->state != H5T_STATE_OPEN) {
3685         if(H5T__free(dt) < 0)
3686             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype");
3687 
3688         dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
3689     } /* end if */
3690     else
3691         /* Free the group hier. path since we're not calling H5T__free() */
3692         H5G_name_free(&(dt->path));
3693 
3694     /* Free the 'top' datatype struct */
3695     dt = H5FL_FREE(H5T_t, dt);
3696 
3697 done:
3698     FUNC_LEAVE_NOAPI(ret_value)
3699 } /* end H5T_close_real() */
3700 
3701 
3702 /*-------------------------------------------------------------------------
3703  * Function: H5T__close_cb
3704  *
3705  * Purpose:  Callback routine for closing a datatype ID.  Closes the datatype
3706  *           object that was attached to the ID.
3707  *
3708  * Return:   Non-negative on success/Negative on failure
3709  *
3710  *-------------------------------------------------------------------------
3711  */
3712 static herr_t
H5T__close_cb(H5T_t * dt)3713 H5T__close_cb(H5T_t *dt)
3714 {
3715     herr_t ret_value = SUCCEED;                 /* Return value */
3716 
3717     FUNC_ENTER_STATIC_VOL
3718 
3719     /* check args */
3720     HDassert(dt && dt->shared);
3721 
3722     /* Call actual datatype close routine */
3723     if(H5T_close(dt) < 0)
3724         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype");
3725 
3726 done:
3727     FUNC_LEAVE_NOAPI_VOL(ret_value)
3728 } /* end H5T__close_cb() */
3729 
3730 
3731 /*-------------------------------------------------------------------------
3732  * Function:  H5T_close
3733  *
3734  * Purpose:   Frees a data type and all associated memory.  Deals with
3735  *            open named datatypes appropriately.
3736  *
3737  * Return:    Non-negative on success/Negative on failure
3738  *
3739  * Programmer:  Robb Matzke
3740  *              Monday, December  8, 1997
3741  *
3742  *-------------------------------------------------------------------------
3743  */
3744 herr_t
H5T_close(H5T_t * dt)3745 H5T_close(H5T_t *dt)
3746 {
3747     herr_t      ret_value = SUCCEED;       /* Return value */
3748 
3749     FUNC_ENTER_NOAPI(FAIL)
3750 
3751     /* Sanity check */
3752     HDassert(dt && dt->shared);
3753 
3754     /* Named datatype cleanups */
3755     if(dt->shared->state == H5T_STATE_OPEN) {
3756         /* Decrement refcount count on open named datatype */
3757         dt->shared->fo_count--;
3758 
3759         /* Sanity checks */
3760         HDassert(dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED);
3761         HDassert(H5F_addr_defined(dt->sh_loc.u.loc.oh_addr));
3762         HDassert(H5F_addr_defined(dt->oloc.addr));
3763 
3764         /*
3765          * If a named type is being closed then close the object header and
3766          * remove from the list of open objects in the file.
3767          */
3768 
3769         /* Decrement the ref. count for this object in the top file */
3770         if(H5FO_top_decr(dt->sh_loc.file, dt->sh_loc.u.loc.oh_addr) < 0)
3771             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
3772 
3773         /* Close things down if this is the last reference to the open named datatype */
3774         if(0 == dt->shared->fo_count) {
3775             hbool_t     corked;            /* Whether the named datatype is corked or not */
3776 
3777             /* Uncork cache entries with object address tag for named datatype */
3778             if(H5AC_cork(dt->oloc.file, dt->oloc.addr, H5AC__GET_CORKED, &corked) < 0)
3779                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status")
3780             if(corked)
3781                 if(H5AC_cork(dt->oloc.file, dt->oloc.addr, H5AC__UNCORK, NULL) < 0)
3782                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTUNCORK, FAIL, "unable to uncork an object")
3783 
3784             /* Remove the datatype from the list of opened objects in the file */
3785             if(H5FO_delete(dt->sh_loc.file, dt->sh_loc.u.loc.oh_addr) < 0)
3786                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't remove datatype from list of open objects")
3787             if(H5O_close(&dt->oloc, NULL) < 0)
3788                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to close data type object header")
3789 
3790             /* Mark named datatype closed now */
3791             dt->shared->state = H5T_STATE_NAMED;
3792         } /* end if */
3793         else {
3794             /* Check reference count for this object in the top file */
3795             if(H5FO_top_count(dt->sh_loc.file, dt->sh_loc.u.loc.oh_addr) == 0) {
3796                 /* Close object location for named datatype */
3797                 if(H5O_close(&dt->oloc, NULL) < 0)
3798                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to close")
3799             } /* end if */
3800             else
3801                 /* Free object location (i.e. "unhold" the file if appropriate) */
3802                 if(H5O_loc_free(&(dt->oloc)) < 0)
3803                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "problem attempting to free location")
3804         } /* end else */
3805     } /* end if */
3806 
3807     /* Clean up resources */
3808     if(H5T_close_real(dt) < 0)
3809         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to free datatype");
3810 
3811 done:
3812     FUNC_LEAVE_NOAPI(ret_value)
3813 } /* end H5T_close() */
3814 
3815 
3816 /*-------------------------------------------------------------------------
3817  * Function:    H5T__set_size
3818  *
3819  * Purpose:    Sets the total size in bytes for a data type (this operation
3820  *        is not permitted on reference data types).  If the size is
3821  *        decreased so that the significant bits of the data type
3822  *        extend beyond the edge of the new size, then the `offset'
3823  *        property is decreased toward zero.  If the `offset' becomes
3824  *        zero and the significant bits of the data type still hang
3825  *        over the edge of the new size, then the number of significant
3826  *        bits is decreased.
3827  *
3828  *        Adjusting the size of an H5T_STRING automatically sets the
3829  *        precision to 8*size.
3830  *
3831  *        All data types have a positive size.
3832  *
3833  * Return:    Success:    non-negative
3834  *
3835  *            Failure:    nagative
3836  *
3837  * Programmer:    Robb Matzke
3838  *              Tuesday, December 22, 1998
3839  *
3840  *-------------------------------------------------------------------------
3841  */
3842 static herr_t
H5T__set_size(H5T_t * dt,size_t size)3843 H5T__set_size(H5T_t *dt, size_t size)
3844 {
3845     size_t    prec, offset;
3846     herr_t    ret_value = SUCCEED;       /* Return value */
3847 
3848     FUNC_ENTER_STATIC
3849 
3850     /* Check args */
3851     HDassert(dt);
3852     HDassert(size!=0);
3853     HDassert(H5T_REFERENCE!=dt->shared->type);
3854     HDassert(!(H5T_ENUM==dt->shared->type && 0==dt->shared->u.enumer.nmembs));
3855 
3856     if(dt->shared->parent) {
3857         if(H5T__set_size(dt->shared->parent, size) < 0)
3858             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size for parent data type");
3859 
3860         /* Adjust size of datatype appropriately */
3861         if(dt->shared->type==H5T_ARRAY)
3862             dt->shared->size = dt->shared->parent->shared->size * dt->shared->u.array.nelem;
3863         else if(dt->shared->type!=H5T_VLEN)
3864             dt->shared->size = dt->shared->parent->shared->size;
3865     } /* end if */
3866     else {
3867         if (H5T_IS_ATOMIC(dt->shared)) {
3868             offset = dt->shared->u.atomic.offset;
3869             prec = dt->shared->u.atomic.prec;
3870 
3871             /* Decrement the offset and precision if necessary */
3872             if (prec > 8*size)
3873                 offset = 0;
3874             else
3875                 if (offset+prec > 8*size)
3876                     offset = 8 * size - prec;
3877             if (prec > 8*size)
3878                 prec = 8 * size;
3879         } /* end if */
3880         else
3881             prec = offset = 0;
3882 
3883         switch(dt->shared->type) {
3884             case H5T_INTEGER:
3885             case H5T_TIME:
3886             case H5T_BITFIELD:
3887             case H5T_OPAQUE:
3888                 /* nothing to check */
3889                 break;
3890 
3891             case H5T_COMPOUND:
3892                 /* If decreasing size, check the last member isn't being cut. */
3893                 if(size < dt->shared->size) {
3894                     int         num_membs = 0;
3895                     unsigned    i, max_index = 0;
3896                     size_t      memb_offset, max_offset = 0;
3897                     size_t      max_size;
3898 
3899                     if((num_membs = H5T_get_nmembers(dt)) < 0)
3900                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to get number of members");
3901 
3902                     if(num_membs) {
3903                         for(i = 0; i < (unsigned)num_membs; i++) {
3904                             memb_offset = H5T_get_member_offset(dt, i);
3905                             if(memb_offset > max_offset) {
3906                                 max_offset = memb_offset;
3907                                 max_index = i;
3908                             } /* end if */
3909                         } /* end for */
3910 
3911                         max_size = H5T__get_member_size(dt, max_index);
3912 
3913                         if(size < (max_offset + max_size))
3914                             HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size shrinking will cut off last member ");
3915                     } /* end if */
3916 
3917                     /* Compound must not have been packed previously */
3918                     /* We will check if resizing changed the packed state of
3919                      * this type at the end of this function */
3920                     HDassert(!dt->shared->u.compnd.packed);
3921                 } /* end if */
3922 
3923                 break;
3924 
3925             case H5T_STRING:
3926                 /* Convert string to variable-length datatype */
3927                 if(size == H5T_VARIABLE) {
3928                     H5T_t       *base = NULL;        /* base data type */
3929                     H5T_cset_t  tmp_cset;            /* Temp. cset info */
3930                     H5T_str_t   tmp_strpad;          /* Temp. strpad info */
3931 
3932                     /* Get a copy of unsigned char type as the base/parent type */
3933                     if(NULL == (base = (H5T_t *)H5I_object(H5T_NATIVE_UCHAR)))
3934                         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid base datatype");
3935                     dt->shared->parent=H5T_copy(base,H5T_COPY_ALL);
3936 
3937                     /* change this datatype into a VL string */
3938                     dt->shared->type = H5T_VLEN;
3939 
3940                     /*
3941                      * Force conversions (i.e. memory to memory conversions
3942                      * should duplicate data, not point to the same VL strings)
3943                      */
3944                     dt->shared->force_conv = TRUE;
3945 
3946                     /* Before we mess with the info in the union, extract the
3947                      * values we need */
3948                     tmp_cset = dt->shared->u.atomic.u.s.cset;
3949                     tmp_strpad = dt->shared->u.atomic.u.s.pad;
3950 
3951                     /* This is a string, not a sequence */
3952                     dt->shared->u.vlen.type = H5T_VLEN_STRING;
3953 
3954                     /* Set character set and padding information */
3955                     dt->shared->u.vlen.cset = tmp_cset;
3956                     dt->shared->u.vlen.pad  = tmp_strpad;
3957 
3958                     /* Set up VL information */
3959                     if (H5T_set_loc(dt, NULL, H5T_LOC_MEMORY)<0)
3960                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location");
3961                 } /* end if */
3962                 else {
3963                     prec = 8 * size;
3964                     offset = 0;
3965                 } /* end else */
3966                 break;
3967 
3968             case H5T_FLOAT:
3969                 /*
3970                  * The sign, mantissa, and exponent fields should be adjusted
3971                  * first when decreasing the size of a floating point type.
3972                  */
3973                 if(dt->shared->u.atomic.u.f.sign >= prec+offset ||
3974                         dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize > prec+offset ||
3975                         dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize > prec+offset) {
3976                     HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first");
3977                 } /* end if */
3978                 break;
3979 
3980             case H5T_ENUM:
3981             case H5T_VLEN:
3982             case H5T_ARRAY:
3983             case H5T_REFERENCE:
3984                 HDassert("can't happen" && 0);
3985                 break;
3986 
3987             case H5T_NO_CLASS:
3988             case H5T_NCLASSES:
3989                 HDassert("invalid type" && 0);
3990                 break;
3991 
3992             default:
3993                 HDassert("not implemented yet" && 0);
3994                 break;
3995         } /* end switch */
3996 
3997         /* Commit (if we didn't convert this type to a VL string) */
3998         if(dt->shared->type != H5T_VLEN) {
3999             dt->shared->size = size;
4000             if (H5T_IS_ATOMIC(dt->shared)) {
4001                 dt->shared->u.atomic.offset = offset;
4002                 dt->shared->u.atomic.prec = prec;
4003             } /* end if */
4004         } /* end if */
4005 
4006         /* Check if the new compound type is packed */
4007         if(dt->shared->type == H5T_COMPOUND)
4008             H5T__update_packed(dt);
4009     } /* end else */
4010 
4011 done:
4012     FUNC_LEAVE_NOAPI(ret_value)
4013 } /* end H5T__set_size() */
4014 
4015 
4016 /*-------------------------------------------------------------------------
4017  * Function:  H5T_get_size
4018  *
4019  * Purpose:   Determines the total size of a data type in bytes.
4020  *
4021  * Return:    Success:    Size of the data type in bytes.     The size of
4022  *                the data type is the size of an instance of
4023  *                that data type.
4024  *
4025  *            Failure:    0 (valid data types are never zero size)
4026  *
4027  * Programmer:    Robb Matzke
4028  *        Tuesday, December  9, 1997
4029  *-------------------------------------------------------------------------
4030  */
4031 size_t
H5T_get_size(const H5T_t * dt)4032 H5T_get_size(const H5T_t *dt)
4033 {
4034     /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
4035     FUNC_ENTER_NOAPI_NOINIT_NOERR
4036 
4037     /* check args */
4038     HDassert(dt);
4039 
4040     FUNC_LEAVE_NOAPI(dt->shared->size)
4041 }
4042 
4043 
4044 /*-------------------------------------------------------------------------
4045  * Function:  H5T_cmp
4046  *
4047  * Purpose:   Compares two data types.
4048  *
4049  * Return:    Success:    0 if DT1 and DT2 are equal.
4050  *                       <0 if DT1 is less than DT2.
4051  *                       >0 if DT1 is greater than DT2.
4052  *
4053  *            Failure:    0, never fails
4054  *
4055  * Programmer:    Robb Matzke
4056  *        Wednesday, December 10, 1997
4057  *
4058  *-------------------------------------------------------------------------
4059  */
4060 int
H5T_cmp(const H5T_t * dt1,const H5T_t * dt2,hbool_t superset)4061 H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset)
4062 {
4063     unsigned    *idx1 = NULL, *idx2 = NULL;
4064     size_t      base_size;
4065     hbool_t     swapped;
4066     unsigned    u;
4067     int         tmp;
4068     int         ret_value = 0;
4069 
4070     FUNC_ENTER_NOAPI(0)
4071 
4072     /* Sanity check */
4073     HDassert(dt1);
4074     HDassert(dt2);
4075 
4076     /* the easy case */
4077     if(dt1 == dt2)
4078         HGOTO_DONE(0);
4079 
4080     /* compare */
4081     if(dt1->shared->type < dt2->shared->type)
4082         HGOTO_DONE(-1);
4083     if(dt1->shared->type > dt2->shared->type)
4084         HGOTO_DONE(1);
4085 
4086     if(dt1->shared->size < dt2->shared->size)
4087         HGOTO_DONE(-1);
4088     if(dt1->shared->size > dt2->shared->size)
4089         HGOTO_DONE(1);
4090 
4091     if(dt1->shared->parent && !dt2->shared->parent)
4092         HGOTO_DONE(-1);
4093     if(!dt1->shared->parent && dt2->shared->parent)
4094         HGOTO_DONE(1);
4095     if(dt1->shared->parent) {
4096         tmp = H5T_cmp(dt1->shared->parent, dt2->shared->parent, superset);
4097         if(tmp < 0)
4098             HGOTO_DONE(-1);
4099         if(tmp > 0)
4100             HGOTO_DONE(1);
4101     } /* end if */
4102 
4103     switch(dt1->shared->type) {
4104         case H5T_COMPOUND:
4105             /*
4106              * Compound data types...
4107              */
4108             if(dt1->shared->u.compnd.nmembs < dt2->shared->u.compnd.nmembs)
4109                 HGOTO_DONE(-1);
4110             if(dt1->shared->u.compnd.nmembs > dt2->shared->u.compnd.nmembs)
4111                 HGOTO_DONE(1);
4112 
4113             /* Build an index for each type so the names are sorted */
4114             if(NULL == (idx1 = (unsigned *)H5MM_malloc(dt1->shared->u.compnd.nmembs * sizeof(unsigned))) ||
4115                     NULL == (idx2 = (unsigned *)H5MM_malloc(dt2->shared->u.compnd.nmembs * sizeof(unsigned))))
4116                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed");
4117             for(u = 0; u < dt1->shared->u.compnd.nmembs; u++)
4118                 idx1[u] = idx2[u] = u;
4119             if(dt1->shared->u.enumer.nmembs > 1) {
4120                 int i;
4121 
4122                 for(i = (int) dt1->shared->u.compnd.nmembs - 1, swapped = TRUE; swapped && i >= 0; --i) {
4123                     int j;
4124 
4125                     for(j = 0, swapped=FALSE; j < i; j++)
4126                         if(HDstrcmp(dt1->shared->u.compnd.memb[idx1[j]].name,
4127                                  dt1->shared->u.compnd.memb[idx1[j + 1]].name) > 0) {
4128                             unsigned tmp_idx = idx1[j];
4129                             idx1[j] = idx1[j + 1];
4130                             idx1[j + 1] = tmp_idx;
4131                             swapped = TRUE;
4132                         }
4133                 }
4134                 for(i = (int) dt2->shared->u.compnd.nmembs - 1, swapped = TRUE; swapped && i >= 0; --i) {
4135                     int j;
4136 
4137                     for(j = 0, swapped = FALSE; j<i; j++)
4138                         if(HDstrcmp(dt2->shared->u.compnd.memb[idx2[j]].name,
4139                                  dt2->shared->u.compnd.memb[idx2[j + 1]].name) > 0) {
4140                             unsigned tmp_idx = idx2[j];
4141                             idx2[j] = idx2[j + 1];
4142                             idx2[j + 1] = tmp_idx;
4143                             swapped = TRUE;
4144                         }
4145                 }
4146             } /* end if */
4147 
4148 #ifdef H5T_DEBUG
4149             /* I don't quite trust the code above yet :-)  --RPM */
4150             for(u=0; u<dt1->shared->u.compnd.nmembs-1; u++) {
4151                 HDassert(HDstrcmp(dt1->shared->u.compnd.memb[idx1[u]].name,
4152                         dt1->shared->u.compnd.memb[idx1[u + 1]].name));
4153                 HDassert(HDstrcmp(dt2->shared->u.compnd.memb[idx2[u]].name,
4154                         dt2->shared->u.compnd.memb[idx2[u + 1]].name));
4155             }
4156 #endif
4157 
4158             /* Compare the members */
4159             for(u=0; u<dt1->shared->u.compnd.nmembs; u++) {
4160                 tmp = HDstrcmp(dt1->shared->u.compnd.memb[idx1[u]].name,
4161                        dt2->shared->u.compnd.memb[idx2[u]].name);
4162                 if(tmp < 0)
4163                     HGOTO_DONE(-1);
4164                 if(tmp > 0)
4165                     HGOTO_DONE(1);
4166 
4167                 if(dt1->shared->u.compnd.memb[idx1[u]].offset < dt2->shared->u.compnd.memb[idx2[u]].offset) HGOTO_DONE(-1);
4168                 if(dt1->shared->u.compnd.memb[idx1[u]].offset > dt2->shared->u.compnd.memb[idx2[u]].offset) HGOTO_DONE(1);
4169 
4170                 if(dt1->shared->u.compnd.memb[idx1[u]].size < dt2->shared->u.compnd.memb[idx2[u]].size) HGOTO_DONE(-1);
4171                 if(dt1->shared->u.compnd.memb[idx1[u]].size > dt2->shared->u.compnd.memb[idx2[u]].size) HGOTO_DONE(1);
4172 
4173                 tmp = H5T_cmp(dt1->shared->u.compnd.memb[idx1[u]].type,
4174                       dt2->shared->u.compnd.memb[idx2[u]].type, superset);
4175                 if(tmp < 0) HGOTO_DONE(-1);
4176                 if(tmp > 0) HGOTO_DONE(1);
4177             }
4178             break;
4179 
4180         case H5T_ENUM:
4181             /*
4182              * Enumeration data types...
4183              */
4184 
4185             /* If we are doing a "superset" comparison, dt2 is allowed to have
4186              * more members than dt1
4187              */
4188             if(superset) {
4189                 if(dt1->shared->u.enumer.nmembs > dt2->shared->u.enumer.nmembs)
4190                     HGOTO_DONE(1);
4191             } /* end if */
4192             else {
4193                 if(dt1->shared->u.enumer.nmembs < dt2->shared->u.enumer.nmembs)
4194                     HGOTO_DONE(-1);
4195                 if(dt1->shared->u.enumer.nmembs > dt2->shared->u.enumer.nmembs)
4196                     HGOTO_DONE(1);
4197             } /* end else */
4198 
4199             /* Build an index for each type so the names are sorted */
4200             if(NULL == (idx1 = (unsigned *)H5MM_malloc(dt1->shared->u.enumer.nmembs * sizeof(unsigned))) ||
4201                     NULL == (idx2 = (unsigned *)H5MM_malloc(dt2->shared->u.enumer.nmembs * sizeof(unsigned))))
4202                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed");
4203             for(u=0; u<dt1->shared->u.enumer.nmembs; u++)
4204                 idx1[u] = u;
4205             if(dt1->shared->u.enumer.nmembs > 1) {
4206                 int i;
4207                 for (i = (int) dt1->shared->u.enumer.nmembs - 1, swapped = TRUE; swapped && i >= 0; --i) {
4208                     int j;
4209 
4210                     for(j = 0, swapped = FALSE; j < i; j++)
4211                         if(HDstrcmp(dt1->shared->u.enumer.name[idx1[j]],
4212                                  dt1->shared->u.enumer.name[idx1[j+1]]) > 0) {
4213                             unsigned tmp_idx = idx1[j];
4214                             idx1[j] = idx1[j+1];
4215                             idx1[j+1] = tmp_idx;
4216                             swapped = TRUE;
4217                         }
4218                 }
4219             }
4220             for(u=0; u<dt2->shared->u.enumer.nmembs; u++)
4221                 idx2[u] = u;
4222             if(dt2->shared->u.enumer.nmembs > 1) {
4223                 int i;
4224 
4225                 for(i = (int) dt2->shared->u.enumer.nmembs - 1, swapped = TRUE; swapped && i >= 0; --i) {
4226                     int j;
4227 
4228                     for(j = 0, swapped = FALSE; j < i; j++)
4229                         if(HDstrcmp(dt2->shared->u.enumer.name[idx2[j]],
4230                                  dt2->shared->u.enumer.name[idx2[j+1]]) > 0) {
4231                             unsigned tmp_idx = idx2[j];
4232                             idx2[j] = idx2[j+1];
4233                             idx2[j+1] = tmp_idx;
4234                             swapped = TRUE;
4235                         }
4236                 }
4237             }
4238 
4239 #ifdef H5T_DEBUG
4240             /* I don't quite trust the code above yet :-)  --RPM */
4241             for(u=0; u<dt1->shared->u.enumer.nmembs-1; u++) {
4242                 HDassert(HDstrcmp(dt1->shared->u.enumer.name[idx1[u]],
4243                         dt1->shared->u.enumer.name[idx1[u+1]]));
4244                 HDassert(HDstrcmp(dt2->shared->u.enumer.name[idx2[u]],
4245                         dt2->shared->u.enumer.name[idx2[u+1]]));
4246             }
4247 #endif
4248 
4249             /* Compare the members */
4250             base_size = dt1->shared->parent->shared->size;
4251             for(u=0; u<dt1->shared->u.enumer.nmembs; u++) {
4252                 unsigned idx = 0;
4253 
4254                 if(superset) {
4255                     unsigned    lt = 0, rt;        /* Final, left & right key indices */
4256                     int            cmp = 1;                /* Key comparison value */
4257 
4258                     /* If a superset is allowed, dt2 may have more members
4259                      * than dt1, so binary search for matching member name in
4260                      * dt2
4261                      */
4262                     rt = dt2->shared->u.enumer.nmembs;
4263 
4264                     while(lt < rt && cmp) {
4265                         idx = (lt + rt) / 2;
4266 
4267                         /* compare */
4268                         if((cmp = HDstrcmp(dt1->shared->u.enumer.name[idx1[u]],
4269                                 dt2->shared->u.enumer.name[idx2[idx]] ) ) < 0)
4270                             rt = idx;
4271                         else
4272                             lt = idx+1;
4273                     }
4274                     /* Leave, if we couldn't find match */
4275                     if(cmp)
4276                         HGOTO_DONE(-1);
4277                 } /* end if */
4278                 else {
4279                     /* Check for exact member name match when not doing
4280                      * "superset" comparison
4281                      */
4282                     tmp = HDstrcmp(dt1->shared->u.enumer.name[idx1[u]],
4283                            dt2->shared->u.enumer.name[idx2[u]]);
4284                     if (tmp<0) HGOTO_DONE(-1);
4285                     if (tmp>0) HGOTO_DONE(1);
4286 
4287                     /* Set index value appropriately */
4288                     idx = u;
4289                 } /* end else */
4290 
4291                 tmp = HDmemcmp(dt1->shared->u.enumer.value+idx1[u]*base_size,
4292                        dt2->shared->u.enumer.value+idx2[idx]*base_size,
4293                        base_size);
4294                 if(tmp<0) HGOTO_DONE(-1);
4295                 if(tmp>0) HGOTO_DONE(1);
4296             }
4297             break;
4298 
4299         case H5T_VLEN:
4300             HDassert(dt1->shared->u.vlen.type>H5T_VLEN_BADTYPE && dt1->shared->u.vlen.type<H5T_VLEN_MAXTYPE);
4301             HDassert(dt2->shared->u.vlen.type>H5T_VLEN_BADTYPE && dt2->shared->u.vlen.type<H5T_VLEN_MAXTYPE);
4302             HDassert(dt1->shared->u.vlen.loc>=H5T_LOC_BADLOC && dt1->shared->u.vlen.loc<H5T_LOC_MAXLOC);
4303             HDassert(dt2->shared->u.vlen.loc>=H5T_LOC_BADLOC && dt2->shared->u.vlen.loc<H5T_LOC_MAXLOC);
4304 
4305             /* Arbitrarily sort sequence VL datatypes before string VL datatypes */
4306             if(dt1->shared->u.vlen.type==H5T_VLEN_SEQUENCE &&
4307                     dt2->shared->u.vlen.type==H5T_VLEN_STRING) {
4308                 HGOTO_DONE(-1);
4309             }
4310             else if(dt1->shared->u.vlen.type==H5T_VLEN_STRING &&
4311                     dt2->shared->u.vlen.type==H5T_VLEN_SEQUENCE) {
4312                 HGOTO_DONE(1);
4313             }
4314             /* Arbitrarily sort VL datatypes in memory before disk */
4315             if(dt1->shared->u.vlen.loc==H5T_LOC_MEMORY &&
4316                     dt2->shared->u.vlen.loc==H5T_LOC_DISK) {
4317                 HGOTO_DONE(-1);
4318             }
4319             else if(dt1->shared->u.vlen.loc==H5T_LOC_DISK &&
4320                     dt2->shared->u.vlen.loc==H5T_LOC_MEMORY) {
4321                 HGOTO_DONE(1);
4322             }
4323             else if(dt1->shared->u.vlen.loc==H5T_LOC_BADLOC &&
4324                     dt2->shared->u.vlen.loc!=H5T_LOC_BADLOC) {
4325                 HGOTO_DONE(1);
4326             }
4327 
4328             /* Don't allow VL types in different files to compare as equal */
4329             if(dt1->shared->u.vlen.f < dt2->shared->u.vlen.f)
4330                 HGOTO_DONE(-1);
4331             if(dt1->shared->u.vlen.f > dt2->shared->u.vlen.f)
4332                 HGOTO_DONE(1);
4333             break;
4334 
4335         case H5T_OPAQUE:
4336             if(dt1->shared->u.opaque.tag && dt2->shared->u.opaque.tag)
4337                 HGOTO_DONE(HDstrcmp(dt1->shared->u.opaque.tag,dt2->shared->u.opaque.tag));
4338             break;
4339 
4340         case H5T_ARRAY:
4341             if(dt1->shared->u.array.ndims < dt2->shared->u.array.ndims)
4342                 HGOTO_DONE(-1);
4343             if(dt1->shared->u.array.ndims > dt2->shared->u.array.ndims)
4344                 HGOTO_DONE(1);
4345 
4346             for(u=0; u<dt1->shared->u.array.ndims; u++) {
4347                 if(dt1->shared->u.array.dim[u] < dt2->shared->u.array.dim[u])
4348                     HGOTO_DONE(-1);
4349                 if(dt1->shared->u.array.dim[u] > dt2->shared->u.array.dim[u])
4350                     HGOTO_DONE(1);
4351             }
4352 
4353             tmp = H5T_cmp(dt1->shared->parent, dt2->shared->parent, superset);
4354             if(tmp < 0)
4355                 HGOTO_DONE(-1);
4356             if(tmp > 0)
4357                 HGOTO_DONE(1);
4358             break;
4359 
4360         case H5T_NO_CLASS:
4361         case H5T_INTEGER:
4362         case H5T_FLOAT:
4363         case H5T_TIME:
4364         case H5T_STRING:
4365         case H5T_BITFIELD:
4366         case H5T_REFERENCE:
4367         case H5T_NCLASSES:
4368         default:
4369             /*
4370              * Atomic datatypes...
4371              */
4372             if(dt1->shared->u.atomic.order < dt2->shared->u.atomic.order) HGOTO_DONE(-1);
4373             if(dt1->shared->u.atomic.order > dt2->shared->u.atomic.order) HGOTO_DONE(1);
4374 
4375             if(dt1->shared->u.atomic.prec < dt2->shared->u.atomic.prec) HGOTO_DONE(-1);
4376             if(dt1->shared->u.atomic.prec > dt2->shared->u.atomic.prec) HGOTO_DONE(1);
4377 
4378             if(dt1->shared->u.atomic.offset < dt2->shared->u.atomic.offset) HGOTO_DONE(-1);
4379             if(dt1->shared->u.atomic.offset > dt2->shared->u.atomic.offset) HGOTO_DONE(1);
4380 
4381             if(dt1->shared->u.atomic.lsb_pad < dt2->shared->u.atomic.lsb_pad) HGOTO_DONE(-1);
4382             if(dt1->shared->u.atomic.lsb_pad > dt2->shared->u.atomic.lsb_pad) HGOTO_DONE(1);
4383 
4384             if(dt1->shared->u.atomic.msb_pad < dt2->shared->u.atomic.msb_pad) HGOTO_DONE(-1);
4385             if(dt1->shared->u.atomic.msb_pad > dt2->shared->u.atomic.msb_pad) HGOTO_DONE(1);
4386 
4387             switch (dt1->shared->type) {
4388                 case H5T_INTEGER:
4389                     if(dt1->shared->u.atomic.u.i.sign < dt2->shared->u.atomic.u.i.sign)
4390                         HGOTO_DONE(-1);
4391                     if(dt1->shared->u.atomic.u.i.sign > dt2->shared->u.atomic.u.i.sign)
4392                         HGOTO_DONE(1);
4393                     break;
4394 
4395                 case H5T_FLOAT:
4396                     if(dt1->shared->u.atomic.u.f.sign < dt2->shared->u.atomic.u.f.sign)
4397                         HGOTO_DONE(-1);
4398                     if(dt1->shared->u.atomic.u.f.sign > dt2->shared->u.atomic.u.f.sign)
4399                         HGOTO_DONE(1);
4400 
4401                     if(dt1->shared->u.atomic.u.f.epos < dt2->shared->u.atomic.u.f.epos)
4402                         HGOTO_DONE(-1);
4403                     if(dt1->shared->u.atomic.u.f.epos > dt2->shared->u.atomic.u.f.epos)
4404                         HGOTO_DONE(1);
4405 
4406                     if(dt1->shared->u.atomic.u.f.esize < dt2->shared->u.atomic.u.f.esize) HGOTO_DONE(-1);
4407                     if(dt1->shared->u.atomic.u.f.esize > dt2->shared->u.atomic.u.f.esize) HGOTO_DONE(1);
4408 
4409                     if(dt1->shared->u.atomic.u.f.ebias < dt2->shared->u.atomic.u.f.ebias) HGOTO_DONE(-1);
4410                     if(dt1->shared->u.atomic.u.f.ebias > dt2->shared->u.atomic.u.f.ebias) HGOTO_DONE(1);
4411 
4412                     if(dt1->shared->u.atomic.u.f.mpos < dt2->shared->u.atomic.u.f.mpos)
4413                         HGOTO_DONE(-1);
4414                     if(dt1->shared->u.atomic.u.f.mpos > dt2->shared->u.atomic.u.f.mpos)
4415                         HGOTO_DONE(1);
4416 
4417                     if(dt1->shared->u.atomic.u.f.msize < dt2->shared->u.atomic.u.f.msize) HGOTO_DONE(-1);
4418                     if(dt1->shared->u.atomic.u.f.msize > dt2->shared->u.atomic.u.f.msize) HGOTO_DONE(1);
4419 
4420                     if(dt1->shared->u.atomic.u.f.norm < dt2->shared->u.atomic.u.f.norm)
4421                         HGOTO_DONE(-1);
4422                     if(dt1->shared->u.atomic.u.f.norm > dt2->shared->u.atomic.u.f.norm)
4423                         HGOTO_DONE(1);
4424 
4425                     if(dt1->shared->u.atomic.u.f.pad < dt2->shared->u.atomic.u.f.pad)
4426                         HGOTO_DONE(-1);
4427                     if(dt1->shared->u.atomic.u.f.pad > dt2->shared->u.atomic.u.f.pad)
4428                         HGOTO_DONE(1);
4429 
4430                     break;
4431 
4432                 case H5T_TIME:  /* order and precision are checked above */
4433                     /*void */
4434                     break;
4435 
4436                 case H5T_STRING:
4437                     if(dt1->shared->u.atomic.u.s.cset < dt2->shared->u.atomic.u.s.cset)
4438                         HGOTO_DONE(-1);
4439                     if(dt1->shared->u.atomic.u.s.cset > dt2->shared->u.atomic.u.s.cset)
4440                         HGOTO_DONE(1);
4441 
4442                     if(dt1->shared->u.atomic.u.s.pad < dt2->shared->u.atomic.u.s.pad)
4443                         HGOTO_DONE(-1);
4444                     if(dt1->shared->u.atomic.u.s.pad > dt2->shared->u.atomic.u.s.pad)
4445                         HGOTO_DONE(1);
4446 
4447                     break;
4448 
4449                 case H5T_BITFIELD:
4450                     /*void */
4451                     break;
4452 
4453                 case H5T_REFERENCE:
4454                     if(dt1->shared->u.atomic.u.r.rtype < dt2->shared->u.atomic.u.r.rtype)
4455                         HGOTO_DONE(-1);
4456                     if(dt1->shared->u.atomic.u.r.rtype > dt2->shared->u.atomic.u.r.rtype)
4457                         HGOTO_DONE(1);
4458 
4459                     switch(dt1->shared->u.atomic.u.r.rtype) {
4460                         case H5R_OBJECT:
4461                             if(dt1->shared->u.atomic.u.r.loc < dt2->shared->u.atomic.u.r.loc)
4462                                 HGOTO_DONE(-1);
4463                             if(dt1->shared->u.atomic.u.r.loc > dt2->shared->u.atomic.u.r.loc)
4464                                 HGOTO_DONE(1);
4465                             break;
4466 
4467                         case H5R_DATASET_REGION:
4468                     /* Does this need more to distinguish it? -QAK 11/30/98 */
4469                             /*void */
4470                             break;
4471 
4472                         case H5R_BADTYPE:
4473                         case H5R_MAXTYPE:
4474                             HDassert("invalid type" && 0);
4475                             break;
4476                         default:
4477                             HDassert("not implemented yet" && 0);
4478                             break;
4479                     }
4480                     break;
4481 
4482                 case H5T_NO_CLASS:
4483                 case H5T_OPAQUE:
4484                 case H5T_COMPOUND:
4485                 case H5T_ENUM:
4486                 case H5T_VLEN:
4487                 case H5T_ARRAY:
4488                 case H5T_NCLASSES:
4489                 default:
4490                     HDassert("not implemented yet" && 0);
4491                     break;
4492             }
4493         break;
4494     } /* end switch */
4495 
4496 done:
4497     if(NULL != idx1)
4498         H5MM_xfree(idx1);
4499     if(NULL != idx2)
4500         H5MM_xfree(idx2);
4501 
4502     FUNC_LEAVE_NOAPI(ret_value)
4503 } /* end H5T_cmp() */
4504 
4505 
4506 /*-------------------------------------------------------------------------
4507  * Function:    H5T_path_find
4508  *
4509  * Purpose:    Library-internal wrapper to find the path which converts type
4510  *              SRC_ID to type DST_ID.
4511  *
4512  *              If SRC and DST are both null pointers then the special no-op
4513  *              conversion path is used.
4514  *
4515  * Return:    Success:    Pointer to the path, valid until the path
4516  *                        database is modified.
4517  *
4518  *            Failure:    NULL if the path does not exist and no
4519  *                        function can be found to apply to the new path.
4520  *
4521  * Programmer:  Quincey Koziol
4522  *              Monday, March 5, 2018
4523  *
4524  *-------------------------------------------------------------------------
4525  */
4526 H5T_path_t *
H5T_path_find(const H5T_t * src,const H5T_t * dst)4527 H5T_path_find(const H5T_t *src, const H5T_t *dst)
4528 {
4529     H5T_conv_func_t conv_func;          /* Conversion function wrapper */
4530     H5T_path_t *ret_value = NULL;       /* Return value */
4531 
4532     FUNC_ENTER_NOAPI(NULL)
4533 
4534     /* Sanity check */
4535     HDassert(src);
4536     HDassert(src->shared);
4537     HDassert(dst);
4538     HDassert(dst->shared);
4539 
4540     /* Set up conversion function wrapper */
4541     conv_func.is_app = FALSE;
4542     conv_func.u.lib_func = NULL;
4543 
4544     /* Call the internal routine, with additional parameters */
4545     if(NULL == (ret_value = H5T__path_find_real(src, dst, NULL, &conv_func)))
4546         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, NULL, "can't find datatype conversion path")
4547 
4548 done:
4549     FUNC_LEAVE_NOAPI(ret_value)
4550 } /* end H5T_path_find() */
4551 
4552 
4553 /*-------------------------------------------------------------------------
4554  * Function:    H5T__path_find_real
4555  *
4556  * Purpose:    Finds the path which converts type SRC_ID to type DST_ID,
4557  *        creating a new path if necessary.  If FUNC is non-zero then
4558  *        it is set as the hard conversion function for that path
4559  *        regardless of whether the path previously existed. Changing
4560  *        the conversion function of a path causes statistics to be
4561  *        reset to zero after printing them.  The NAME is used only
4562  *        when creating a new path and is just for debugging.
4563  *
4564  *        If SRC and DST are both null pointers then the special no-op
4565  *        conversion path is used.  This path is always stored as the
4566  *        first path in the path table.
4567  *
4568  * Return:    Success:    Pointer to the path, valid until the path
4569  *                        database is modified.
4570  *
4571  *            Failure:    NULL if the path does not exist and no
4572  *                        function can be found to apply to the new path.
4573  *
4574  * Programmer:  Robb Matzke
4575  *              Tuesday, January 13, 1998
4576  *
4577  *-------------------------------------------------------------------------
4578  */
4579 static H5T_path_t *
H5T__path_find_real(const H5T_t * src,const H5T_t * dst,const char * name,H5T_conv_func_t * conv)4580 H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name,
4581     H5T_conv_func_t *conv)
4582 {
4583     int           lt, rt;                      /* left and right edges */
4584     int           md;                          /* middle */
4585     int           cmp;                         /* comparison result  */
4586     int           old_npaths;                  /* Previous number of paths in table */
4587     H5T_path_t    *table = NULL;               /* path existing in the table */
4588     H5T_path_t    *path = NULL;                /* new path */
4589     hid_t         src_id = -1, dst_id = -1;    /* src and dst type identifiers */
4590     int           i;                           /* counter */
4591     int           nprint = 0;                  /* lines of output printed */
4592     H5T_path_t    *ret_value = NULL;           /* Return value */
4593 
4594     FUNC_ENTER_STATIC
4595 
4596     /* Sanity check */
4597     HDassert(src);
4598     HDassert(src->shared);
4599     HDassert(dst);
4600     HDassert(dst->shared);
4601 
4602     /*
4603      * Make sure the first entry in the table is the no-op conversion path.
4604      */
4605     if(0 == H5T_g.npaths) {
4606         if(NULL == (H5T_g.path = (H5T_path_t **)H5MM_malloc(128 * sizeof(H5T_path_t *))))
4607             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path table")
4608         H5T_g.apaths = 128;
4609         if(NULL == (H5T_g.path[0] = H5FL_CALLOC(H5T_path_t)))
4610             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for no-op conversion path")
4611         HDsnprintf(H5T_g.path[0]->name, sizeof(H5T_g.path[0]->name), "no-op");
4612         H5T_g.path[0]->conv.is_app = FALSE;
4613         H5T_g.path[0]->conv.u.lib_func = H5T__conv_noop;
4614         H5T_g.path[0]->cdata.command = H5T_CONV_INIT;
4615         if(H5T__conv_noop((hid_t)FAIL, (hid_t)FAIL, &(H5T_g.path[0]->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
4616 #ifdef H5T_DEBUG
4617             if(H5DEBUG(T))
4618                 fprintf(H5DEBUG(T), "H5T: unable to initialize no-op conversion function (ignored)\n");
4619 #endif
4620             H5E_clear_stack(NULL); /*ignore the error*/
4621         } /* end if */
4622         H5T_g.path[0]->is_noop = TRUE;
4623         H5T_g.npaths = 1;
4624     } /* end if */
4625 
4626     /*
4627      * Find the conversion path.  If source and destination types are equal
4628      * then use entry[0], otherwise do a binary search over the
4629      * remaining entries.
4630      *
4631      * Quincey Koziol, 2 July, 1999
4632      * Only allow the no-op conversion to occur if no "force conversion" flags
4633      * are set
4634      */
4635     if(src->shared->force_conv == FALSE && dst->shared->force_conv == FALSE && 0 == H5T_cmp(src, dst, TRUE)) {
4636         table = H5T_g.path[0];
4637         cmp = 0;
4638         md = 0;
4639     } /* end if */
4640     else {
4641         lt = md = 1;
4642         rt = H5T_g.npaths;
4643         cmp = -1;
4644 
4645         while(cmp && lt < rt) {
4646             md = (lt + rt) / 2;
4647             HDassert(H5T_g.path[md]);
4648             cmp = H5T_cmp(src, H5T_g.path[md]->src, FALSE);
4649             if(0 == cmp)
4650                 cmp = H5T_cmp(dst, H5T_g.path[md]->dst, FALSE);
4651             if(cmp < 0)
4652                 rt = md;
4653             else if(cmp > 0)
4654                 lt = md + 1;
4655             else
4656                 table = H5T_g.path[md];
4657         } /* end while */
4658     } /* end else */
4659 
4660     /* Keep a record of the number of paths in the table, in case one of the
4661      * initialization calls below (hard or soft) causes more entries to be
4662      * added to the table - QAK, 1/26/02
4663      */
4664     old_npaths = H5T_g.npaths;
4665 
4666     /*
4667      * If we didn't find the path, if the caller is an API function specifying
4668      * a new hard conversion function, or if the caller is a private function
4669      * specifying a new hard conversion and the path is a soft conversion, then
4670      * create a new path and add the new function to the path.
4671      */
4672     if(!table || (table && conv->is_app && conv->u.app_func) || (table && !table->is_hard && !conv->is_app && conv->u.lib_func)) {
4673         if(NULL == (path = H5FL_CALLOC(H5T_path_t)))
4674             HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path")
4675         if(name && *name) {
4676             HDstrncpy(path->name, name, (size_t)H5T_NAMELEN);
4677             path->name[H5T_NAMELEN - 1] = '\0';
4678         } /* end if */
4679         else
4680             HDsnprintf(path->name, sizeof(path->name), "NONAME");
4681         if(NULL == (path->src = H5T_copy(src, H5T_COPY_ALL)))
4682             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy datatype for conversion path")
4683         if(NULL == (path->dst = H5T_copy(dst, H5T_COPY_ALL)))
4684             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy datatype for conversion path")
4685     } /* end if */
4686     else
4687         path = table;
4688 
4689     /*
4690      * If a hard conversion function is specified and none is defined for the
4691      * path, or the caller is an API function, or the caller is a private function but
4692      * the existing path is a soft function, then add the new conversion to the path
4693      * and initialize its conversion data.
4694      */
4695     if(conv->u.app_func && (!table || (table && conv->is_app) || (table && !table->is_hard && !conv->is_app))) {
4696         HDassert(path != table);
4697         HDassert(NULL == path->conv.u.app_func);
4698         if(path->src && (src_id = H5I_register(H5I_DATATYPE, H5T_copy(path->src, H5T_COPY_ALL), FALSE)) < 0)
4699             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source conversion type for query")
4700         if(path->dst && (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(path->dst, H5T_COPY_ALL), FALSE)) < 0)
4701             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination conversion type for query")
4702         path->cdata.command = H5T_CONV_INIT;
4703         if(conv->is_app) {
4704             if((conv->u.app_func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0)
4705                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function")
4706         } /* end if */
4707         else
4708             if((conv->u.lib_func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0)
4709                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function")
4710         if(src_id >= 0)
4711             H5I_dec_ref(src_id);
4712         if(dst_id >= 0)
4713             H5I_dec_ref(dst_id);
4714         src_id = dst_id = -1;
4715         path->conv = *conv;
4716         path->is_hard = TRUE;
4717     } /* end if */
4718 
4719     /*
4720      * If the path doesn't have a function by now (because it's a new path
4721      * and the caller didn't supply a hard function) then scan the soft list
4722      * for an applicable function and add it to the path.  This can't happen
4723      * for the no-op conversion path.
4724      */
4725     HDassert(path->conv.u.app_func || (src && dst));
4726     for(i = H5T_g.nsoft - 1; i >= 0 && !path->conv.u.app_func; --i) {
4727         hbool_t path_init_error = FALSE;
4728 
4729         if(src->shared->type != H5T_g.soft[i].src || dst->shared->type != H5T_g.soft[i].dst)
4730             continue;
4731         if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(path->src, H5T_COPY_ALL), FALSE)) < 0)
4732             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register src conversion type for query")
4733            if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(path->dst, H5T_COPY_ALL), FALSE)) < 0)
4734             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register dst conversion type for query")
4735         path->cdata.command = H5T_CONV_INIT;
4736         if(H5T_g.soft[i].conv.is_app) {
4737             if((H5T_g.soft[i].conv.u.app_func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
4738                 HDmemset(&(path->cdata), 0, sizeof(H5T_cdata_t));
4739                 H5E_clear_stack(H5E_DEFAULT); /*ignore the error*/
4740                 path_init_error = TRUE;
4741             } /* end if */
4742         } /* end if */
4743         else
4744             if((H5T_g.soft[i].conv.u.lib_func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
4745                 HDmemset(&(path->cdata), 0, sizeof(H5T_cdata_t));
4746                 H5E_clear_stack(H5E_DEFAULT); /*ignore the error*/
4747                 path_init_error = TRUE;
4748             } /* end if */
4749 
4750         /* Finish operation, if no error */
4751         if(!path_init_error) {
4752             HDstrncpy(path->name, H5T_g.soft[i].name, (size_t)H5T_NAMELEN);
4753             path->name[H5T_NAMELEN - 1] = '\0';
4754             path->conv = H5T_g.soft[i].conv;
4755             path->is_hard = FALSE;
4756         } /* end else */
4757         H5I_dec_ref(src_id);
4758         H5I_dec_ref(dst_id);
4759         src_id = dst_id = -1;
4760     } /* end for */
4761     if(!path->conv.u.app_func)
4762         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no appropriate function for conversion path")
4763 
4764     /* Check if paths were inserted into the table through a recursive call
4765      * and re-compute the correct location for this path if so. - QAK, 1/26/02
4766      */
4767     if(old_npaths != H5T_g.npaths) {
4768         lt = md = 1;
4769         rt = H5T_g.npaths;
4770         cmp = -1;
4771 
4772         while(cmp && lt < rt) {
4773             md = (lt + rt) / 2;
4774             HDassert(H5T_g.path[md]);
4775             cmp = H5T_cmp(src, H5T_g.path[md]->src, FALSE);
4776             if(0 == cmp)
4777                 cmp = H5T_cmp(dst, H5T_g.path[md]->dst, FALSE);
4778             if(cmp < 0)
4779                 rt = md;
4780             else if(cmp > 0)
4781                 lt = md + 1;
4782             else
4783                 table = H5T_g.path[md];
4784         } /* end while */
4785     } /* end if */
4786 
4787     /* Replace an existing table entry or add a new entry */
4788     if(table && path != table) {
4789         HDassert(table == H5T_g.path[md]);
4790         H5T__print_stats(table, &nprint/*in,out*/);
4791         table->cdata.command = H5T_CONV_FREE;
4792         if(table->conv.is_app) {
4793             if((table->conv.u.app_func)((hid_t)FAIL, (hid_t)FAIL, &(table->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
4794 #ifdef H5T_DEBUG
4795                 if(H5DEBUG(T))
4796                     fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx free failed for %s (ignored)\n",
4797                             (unsigned long)(path->conv.u.app_func), path->name);
4798 #endif
4799                 H5E_clear_stack(NULL); /*ignore the failure*/
4800             } /* end if */
4801         } /* end if */
4802         else
4803             if((table->conv.u.lib_func)((hid_t)FAIL, (hid_t)FAIL, &(table->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL) < 0) {
4804 #ifdef H5T_DEBUG
4805                 if(H5DEBUG(T))
4806                     fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx free failed for %s (ignored)\n",
4807                             (unsigned long)(path->conv.u.lib_func), path->name);
4808 #endif
4809                 H5E_clear_stack(NULL); /*ignore the failure*/
4810             } /* end if */
4811         if(table->src)
4812             (void)H5T_close_real(table->src);
4813         if(table->dst)
4814             (void)H5T_close_real(table->dst);
4815         table = H5FL_FREE(H5T_path_t, table);
4816         table = path;
4817         H5T_g.path[md] = path;
4818     } /* end if */
4819     else if(path != table) {
4820         HDassert(cmp);
4821         if((size_t)H5T_g.npaths >= H5T_g.apaths) {
4822             size_t na = MAX(128, 2 * H5T_g.apaths);
4823             H5T_path_t **x;
4824 
4825             if(NULL == (x = (H5T_path_t **)H5MM_realloc(H5T_g.path, na * sizeof(H5T_path_t*))))
4826                 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
4827             H5T_g.apaths = na;
4828             H5T_g.path = x;
4829         } /* end if */
4830         if(cmp > 0)
4831             md++;
4832         HDmemmove(H5T_g.path + md + 1, H5T_g.path + md, (size_t) (H5T_g.npaths - md) * sizeof(H5T_path_t*));
4833         H5T_g.npaths++;
4834         H5T_g.path[md] = path;
4835         table = path;
4836     } /* end else-if */
4837 
4838     /* Set the flag to indicate both source and destination types are compound types
4839      * for the optimization of data reading (in H5Dio.c). */
4840     if(H5T_COMPOUND == H5T_get_class(src, TRUE) && H5T_COMPOUND == H5T_get_class(dst, TRUE))
4841         path->are_compounds = TRUE;
4842 
4843     /* Set return value */
4844     ret_value = path;
4845 
4846 done:
4847     if(!ret_value && path && path != table) {
4848         if(path->src)
4849             (void)H5T_close_real(path->src);
4850         if(path->dst)
4851             (void)H5T_close_real(path->dst);
4852         path = H5FL_FREE(H5T_path_t, path);
4853     } /* end if */
4854     if(src_id >= 0)
4855         H5I_dec_ref(src_id);
4856     if(dst_id >= 0)
4857         H5I_dec_ref(dst_id);
4858 
4859     FUNC_LEAVE_NOAPI(ret_value)
4860 } /* end H5T__path_find_real() */
4861 
4862 
4863 /*-------------------------------------------------------------------------
4864  * Function:  H5T_path_noop
4865  *
4866  * Purpose:   Is the path the special no-op path? The no-op function can be
4867  *            set by the application and there might be more than one no-op
4868  *            path in a multi-threaded application if one thread is using
4869  *            the no-op path when some other thread changes its definition.
4870  *
4871  * Return:    TRUE/FALSE (can't fail)
4872  *
4873  * Programmer:    Quincey Koziol
4874  *        Thursday, May  8, 2003
4875  *-------------------------------------------------------------------------
4876  */
4877 hbool_t
H5T_path_noop(const H5T_path_t * p)4878 H5T_path_noop(const H5T_path_t *p)
4879 {
4880     FUNC_ENTER_NOAPI_NOINIT_NOERR
4881 
4882     HDassert(p);
4883 
4884     FUNC_LEAVE_NOAPI(p->is_noop || (p->is_hard && 0==H5T_cmp(p->src, p->dst, FALSE)))
4885 } /* end H5T_path_noop() */
4886 
4887 
4888 /*-------------------------------------------------------------------------
4889  * Function:  H5T_path_compound_subset
4890  *
4891  * Purpose:   Checks if the source and destination types are both compound.
4892  *            Tells whether whether the source members are a subset of
4893  *            destination, and the order is the same, and no conversion
4894  *            is needed.  For example:
4895  *                  struct source {            struct destination {
4896  *                      TYPE1 A;      -->          TYPE1 A;
4897  *                      TYPE2 B;      -->          TYPE2 B;
4898  *                      TYPE3 C;      -->          TYPE3 C;
4899  *                  };                             TYPE4 D;
4900  *                                                 TYPE5 E;
4901  *                                             };
4902  *
4903  * Return:    A pointer to the subset info struct in p, or NULL if there are
4904  *            no compounds.  Points directly into the H5T_path_t structure.
4905  *
4906  * Programmer:    Raymond Lu
4907  *        8 June 2007
4908  *
4909  * Modifications:  Neil Fortner
4910  *      19 September 2008
4911  *      Changed return value to H5T_subset_info_t
4912  *      (to allow it to return copy_size)
4913  *
4914  *-------------------------------------------------------------------------
4915  */
4916 H5T_subset_info_t *
H5T_path_compound_subset(const H5T_path_t * p)4917 H5T_path_compound_subset(const H5T_path_t *p)
4918 {
4919     H5T_subset_info_t *ret_value = NULL;
4920 
4921     FUNC_ENTER_NOAPI_NOINIT_NOERR
4922 
4923     HDassert(p);
4924 
4925     if(p->are_compounds)
4926         ret_value = H5T__conv_struct_subset(&(p->cdata));
4927 
4928     FUNC_LEAVE_NOAPI(ret_value)
4929 } /* end H5T_path_compound_subset */
4930 
4931 
4932 /*-------------------------------------------------------------------------
4933  * Function:  H5T_path_bkg
4934  *
4935  * Purpose:   Get the "background" flag for the conversion path.
4936  *
4937  * Return:    Background flag (can't fail)
4938  *
4939  * Programmer:    Quincey Koziol
4940  *        Thursday, May  8, 2003
4941  *-------------------------------------------------------------------------
4942  */
4943 H5T_bkg_t
H5T_path_bkg(const H5T_path_t * p)4944 H5T_path_bkg(const H5T_path_t *p)
4945 {
4946     FUNC_ENTER_NOAPI_NOINIT_NOERR
4947 
4948     HDassert(p);
4949 
4950     FUNC_LEAVE_NOAPI(p->cdata.need_bkg)
4951 } /* end H5T_path_bkg() */
4952 
4953 
4954 /*-------------------------------------------------------------------------
4955  * Function:  H5T__compiler_conv
4956  *
4957  * Purpose:   Private function for H5Tcompiler_conv.  Finds out whether the
4958  *            library's conversion function from type SRC to type DST
4959  *            is a hard conversion.
4960  *
4961  * Return:    TRUE:           hard conversion.
4962  *            FALSE:          soft conversion.
4963  *            FAIL:           function failed.
4964  *
4965  * Programmer:    Raymond Lu
4966  *        Friday, Sept 2, 2005
4967  *-------------------------------------------------------------------------
4968  */
4969 static htri_t
H5T__compiler_conv(H5T_t * src,H5T_t * dst)4970 H5T__compiler_conv(H5T_t *src, H5T_t *dst)
4971 {
4972     H5T_path_t    *path;
4973     htri_t    ret_value = FAIL;       /* Return value */
4974 
4975     FUNC_ENTER_STATIC
4976 
4977     /* Find it */
4978     if(NULL == (path = H5T_path_find(src, dst)))
4979         HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "conversion function not found")
4980 
4981     ret_value = (htri_t)path->is_hard;
4982 
4983 done:
4984     FUNC_LEAVE_NOAPI(ret_value)
4985 } /* end H5T__compiler_conv() */
4986 
4987 
4988 /*-------------------------------------------------------------------------
4989  * Function:  H5T_convert
4990  *
4991  * Purpose:   Call a conversion function to convert from source to
4992  *            destination data type and accumulate timing statistics.
4993  *
4994  * Return:    Success:    non-negative
4995  *
4996  *            Failure:    negative
4997  *
4998  * Programmer:    Robb Matzke
4999  *              Tuesday, December 15, 1998
5000  *
5001  *-------------------------------------------------------------------------
5002  */
5003 herr_t
H5T_convert(H5T_path_t * tpath,hid_t src_id,hid_t dst_id,size_t nelmts,size_t buf_stride,size_t bkg_stride,void * buf,void * bkg)5004 H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, size_t nelmts,
5005     size_t buf_stride, size_t bkg_stride, void *buf, void *bkg)
5006 {
5007 #ifdef H5T_DEBUG
5008     H5_timer_t        timer;
5009 #endif
5010     herr_t ret_value = SUCCEED;         /* Return value */
5011 
5012     FUNC_ENTER_NOAPI(FAIL)
5013 
5014 #ifdef H5T_DEBUG
5015     if(H5DEBUG(T))
5016         H5_timer_begin(&timer);
5017 #endif
5018     tpath->cdata.command = H5T_CONV_CONV;
5019     if(tpath->conv.is_app) {
5020         if((tpath->conv.u.app_func)(src_id, dst_id, &(tpath->cdata), nelmts, buf_stride, bkg_stride, buf, bkg, H5CX_get_dxpl()) < 0)
5021             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "datatype conversion failed")
5022     } /* end if */
5023     else
5024         if((tpath->conv.u.lib_func)(src_id, dst_id, &(tpath->cdata), nelmts, buf_stride, bkg_stride, buf, bkg) < 0)
5025             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "datatype conversion failed")
5026 #ifdef H5T_DEBUG
5027     if(H5DEBUG(T)) {
5028         H5_timer_end(&(tpath->stats.timer), &timer);
5029         tpath->stats.ncalls++;
5030         tpath->stats.nelmts += nelmts;
5031     } /* end if */
5032 #endif
5033 
5034 done:
5035     FUNC_LEAVE_NOAPI(ret_value)
5036 } /* end H5T_convert() */
5037 
5038 
5039 /*-------------------------------------------------------------------------
5040  * Function:  H5T_oloc
5041  *
5042  * Purpose:   Returns a pointer to the object location for a named datatype.
5043  *
5044  * Return:    Success:    Ptr directly into named datatype
5045  *            Failure:    NULL
5046  *
5047  * Programmer:    Robb Matzke
5048  *              Friday, June  5, 1998
5049  *
5050  *-------------------------------------------------------------------------
5051  */
5052 H5O_loc_t *
H5T_oloc(H5T_t * dt)5053 H5T_oloc(H5T_t *dt)
5054 {
5055     H5O_loc_t *ret_value = NULL;
5056 
5057     FUNC_ENTER_NOAPI(NULL)
5058 
5059     HDassert(dt);
5060 
5061     switch(dt->shared->state) {
5062         case H5T_STATE_TRANSIENT:
5063         case H5T_STATE_RDONLY:
5064         case H5T_STATE_IMMUTABLE:
5065             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "not a named datatype")
5066         case H5T_STATE_NAMED:
5067         case H5T_STATE_OPEN:
5068             HDassert(dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED);
5069             ret_value = &dt->oloc;
5070             break;
5071         default:
5072             HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid datatype state")
5073     } /* end switch */
5074 
5075 done:
5076     FUNC_LEAVE_NOAPI(ret_value)
5077 } /* end H5T_oloc() */
5078 
5079 
5080 /*-------------------------------------------------------------------------
5081  * Function:  H5T_nameof
5082  *
5083  * Purpose:   Returns a pointer to the path for a named datatype.
5084  *
5085  * Return:    Success:    Ptr directly into named datatype
5086  *            Failure:    NULL
5087  *
5088  * Programmer:    Quincey Koziol
5089  *              Monday, September 12, 2005
5090  *
5091  *-------------------------------------------------------------------------
5092  */
5093 H5G_name_t *
H5T_nameof(H5T_t * dt)5094 H5T_nameof(H5T_t *dt)
5095 {
5096     H5G_name_t *ret_value = NULL;
5097 
5098     FUNC_ENTER_NOAPI(NULL)
5099 
5100     HDassert(dt);
5101 
5102     switch(dt->shared->state) {
5103         case H5T_STATE_TRANSIENT:
5104         case H5T_STATE_RDONLY:
5105         case H5T_STATE_IMMUTABLE:
5106             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "not a named datatype")
5107         case H5T_STATE_NAMED:
5108         case H5T_STATE_OPEN:
5109             ret_value = &(dt->path);
5110             break;
5111         default:
5112             HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid datatype state")
5113     } /* end switch */
5114 
5115 done:
5116     FUNC_LEAVE_NOAPI(ret_value)
5117 } /* end H5T_nameof() */
5118 
5119 
5120 /*-------------------------------------------------------------------------
5121  * Function:    H5T_is_immutable
5122  *
5123  * Purpose:     Check if a datatype is immutable.
5124  *
5125  * Return:      TRUE
5126  *
5127  *              FALSE
5128  *
5129  * Programmer:  Raymond Lu
5130  *              Friday, Dec 7, 2001
5131  *-------------------------------------------------------------------------
5132  */
5133 htri_t
H5T_is_immutable(const H5T_t * dt)5134 H5T_is_immutable(const H5T_t *dt)
5135 {
5136     htri_t ret_value = FALSE;
5137 
5138     FUNC_ENTER_NOAPI(FAIL)
5139 
5140     HDassert(dt);
5141 
5142     if(dt->shared->state == H5T_STATE_IMMUTABLE)
5143         ret_value = TRUE;
5144 
5145 done:
5146     FUNC_LEAVE_NOAPI(ret_value)
5147 }
5148 
5149 
5150 /*-------------------------------------------------------------------------
5151  * Function:    H5T_is_named
5152  *
5153  * Purpose:     Check if a datatype is named.
5154  *
5155  * Return:      TRUE
5156  *
5157  *              FALSE
5158  *
5159  * Programmer:  Pedro Vicente
5160  *              Tuesday, Sep 3, 2002
5161  *-------------------------------------------------------------------------
5162  */
5163 htri_t
H5T_is_named(const H5T_t * dt)5164 H5T_is_named(const H5T_t *dt)
5165 {
5166     htri_t ret_value = FALSE;
5167 
5168     FUNC_ENTER_NOAPI(FAIL)
5169 
5170     HDassert(dt);
5171 
5172     if(dt->shared->state == H5T_STATE_OPEN || dt->shared->state == H5T_STATE_NAMED)
5173         ret_value = TRUE;
5174 
5175 done:
5176     FUNC_LEAVE_NOAPI(ret_value)
5177 }
5178 
5179 /*-------------------------------------------------------------------------
5180  * Function:    H5T_convert_committed_datatype
5181  *
5182  * Purpose:     To convert the committed datatype "dt" to a transient embedded
5183  *        type if the file location associated with the committed datatype is
5184  *        different from the parameter "f".
5185  *        "f" is the file location where the dataset or attribute will be created.
5186  *
5187  * Notes:       See HDFFV-9940
5188  *
5189  * Return:      Success:        non-negative
5190  *              Failure:        negative
5191  *
5192  * Programmer:  Vailin Choi; June 2016
5193  *
5194  *-------------------------------------------------------------------------
5195  */
5196 herr_t
H5T_convert_committed_datatype(H5T_t * dt,H5F_t * f)5197 H5T_convert_committed_datatype(H5T_t *dt, H5F_t *f)
5198 {
5199     herr_t      ret_value = SUCCEED;       /* Return value */
5200 
5201     FUNC_ENTER_NOAPI(FAIL)
5202 
5203     HDassert(dt);
5204     HDassert(f);
5205 
5206     if(H5T_is_named(dt) && (dt->sh_loc.file != f)) {
5207        HDassert(dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED);
5208 
5209         H5O_msg_reset_share(H5O_DTYPE_ID, dt);
5210         if(H5O_loc_free(&dt->oloc) < 0)
5211             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to initialize location")
5212         if(H5G_name_free(&dt->path) < 0)
5213             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to reset path")
5214 
5215         dt->shared->state = H5T_STATE_TRANSIENT;
5216     } /* end if */
5217 
5218 done:
5219     FUNC_LEAVE_NOAPI(ret_value)
5220 }   /* end H5T_convert_committed_datatype() */
5221 
5222 
5223 /*--------------------------------------------------------------------------
5224  * Function:    H5T_get_ref_type
5225  *
5226  * Purpose:     Retrieves the type of reference for a datatype
5227  *              H5T_t *dt;  IN: datatype pointer for the reference datatype
5228  *
5229  * Return:      Success:        A reference type defined in H5Rpublic.h
5230  *              Failure:        H5R_BADTYPE
5231  * Notes:       Given a reference datatype object, this function returns the reference type
5232  *              of the datatype.
5233  *--------------------------------------------------------------------------
5234  */
5235 H5R_type_t
H5T_get_ref_type(const H5T_t * dt)5236 H5T_get_ref_type(const H5T_t *dt)
5237 {
5238     H5R_type_t ret_value = H5R_BADTYPE;
5239 
5240     FUNC_ENTER_NOAPI(H5R_BADTYPE)
5241 
5242     HDassert(dt);
5243 
5244     if(dt->shared->type==H5T_REFERENCE)
5245         ret_value=dt->shared->u.atomic.u.r.rtype;
5246 
5247 done:
5248     FUNC_LEAVE_NOAPI(ret_value)
5249 }   /* end H5T_get_ref_type() */
5250 
5251 
5252 /*-------------------------------------------------------------------------
5253  * Function:  H5T_is_sensible
5254  *
5255  * Purpose:   Determines if a data type is sensible to store on disk
5256  *            (i.e. not partially initialized)
5257  *
5258  * Return:    Success:    TRUE, FALSE
5259  *
5260  *            Failure:    Negative
5261  *
5262  * Programmer:    Quincey Koziol
5263  *        Tuesday, June 11, 2002
5264  *-------------------------------------------------------------------------
5265  */
5266 htri_t
H5T_is_sensible(const H5T_t * dt)5267 H5T_is_sensible(const H5T_t *dt)
5268 {
5269     htri_t    ret_value = FAIL;       /* Return value */
5270 
5271     FUNC_ENTER_NOAPI(FAIL)
5272 
5273     HDassert(dt);
5274 
5275     switch(dt->shared->type) {
5276         case H5T_COMPOUND:
5277             /* Only allow compound datatypes with at least one member to be stored on disk */
5278             if(dt->shared->u.compnd.nmembs > 0)
5279                 ret_value=TRUE;
5280             else
5281                 ret_value=FALSE;
5282             break;
5283 
5284         case H5T_ENUM:
5285             /* Only allow enum datatypes with at least one member to be stored on disk */
5286             if(dt->shared->u.enumer.nmembs > 0)
5287                 ret_value=TRUE;
5288             else
5289                 ret_value=FALSE;
5290             break;
5291 
5292         case H5T_NO_CLASS:
5293         case H5T_INTEGER:
5294         case H5T_FLOAT:
5295         case H5T_TIME:
5296         case H5T_STRING:
5297         case H5T_BITFIELD:
5298         case H5T_OPAQUE:
5299         case H5T_REFERENCE:
5300         case H5T_VLEN:
5301         case H5T_ARRAY:
5302         case H5T_NCLASSES:
5303         default:
5304             /* Assume all other datatype are sensible to store on disk */
5305             ret_value=TRUE;
5306             break;
5307     } /* end switch */
5308 
5309 done:
5310     FUNC_LEAVE_NOAPI(ret_value)
5311 }
5312 
5313 
5314 /*--------------------------------------------------------------------------
5315  NAME
5316     H5T_set_loc
5317  PURPOSE
5318     Recursively mark any datatypes as on disk/in memory
5319  USAGE
5320     htri_t H5T_set_loc(dt,f,loc)
5321         H5T_t *dt;              IN/OUT: Pointer to the datatype to mark
5322         H5F_t *f;               IN: Pointer to the file the datatype is in
5323         H5T_vlen_type_t loc     IN: location of type
5324 
5325  RETURNS
5326     One of two values on success:
5327         TRUE - If the location of any vlen types changed
5328         FALSE - If the location of any vlen types is the same
5329     <0 is returned on failure
5330  DESCRIPTION
5331     Recursively descends any VL or compound datatypes to mark all VL datatypes
5332     as either on disk or in memory.
5333  --------------------------------------------------------------------------
5334  */
5335 htri_t
H5T_set_loc(H5T_t * dt,H5F_t * f,H5T_loc_t loc)5336 H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
5337 {
5338     htri_t      changed;         /* Whether H5T_set_loc changed the type (even if the size didn't change) */
5339     htri_t      ret_value = 0;   /* Indicate that success, but no location change */
5340     unsigned    i;               /* Local index variable */
5341     size_t      old_size;        /* Previous size of a field */
5342 
5343     FUNC_ENTER_NOAPI(FAIL)
5344 
5345     HDassert(dt);
5346     HDassert(loc>=H5T_LOC_BADLOC && loc<H5T_LOC_MAXLOC);
5347 
5348     /* Datatypes can't change in size if the force_conv flag is not set */
5349     if(dt->shared->force_conv) {
5350         /* Check the datatype of this element */
5351         switch(dt->shared->type) {
5352             case H5T_ARRAY:  /* Recurse on VL, compound and array base element type */
5353                 /* Recurse if it's VL, compound, enum or array */
5354                 /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
5355                 if(dt->shared->parent->shared->force_conv && H5T_IS_COMPLEX(dt->shared->parent->shared->type)) {
5356                     /* Keep the old base element size for later */
5357                     old_size=dt->shared->parent->shared->size;
5358 
5359                     /* Mark the VL, compound or array type */
5360                     if((changed=H5T_set_loc(dt->shared->parent,f,loc))<0)
5361                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
5362                     if(changed>0)
5363                         ret_value=changed;
5364 
5365                     /* Check if the field changed size */
5366                     if(old_size != dt->shared->parent->shared->size) {
5367                         /* Adjust the size of the array */
5368                         dt->shared->size = dt->shared->u.array.nelem*dt->shared->parent->shared->size;
5369                     } /* end if */
5370                 } /* end if */
5371                 break;
5372 
5373             case H5T_COMPOUND:  /* Check each field and recurse on VL, compound and array type */
5374                 {
5375                     ssize_t accum_change = 0; /* Amount of change in the offset of the fields */
5376 
5377                     /* Sort the fields based on offsets */
5378                     H5T__sort_value(dt, NULL);
5379 
5380                     for (i = 0; i < dt->shared->u.compnd.nmembs; i++) {
5381                         H5T_t *memb_type;   /* Member's datatype pointer */
5382 
5383                         /* Range check against compound member's offset */
5384                         if ((accum_change < 0) && ((ssize_t) dt->shared->u.compnd.memb[i].offset < accum_change))
5385                             HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype");
5386 
5387                         /* Apply the accumulated size change to the offset of the field */
5388                         dt->shared->u.compnd.memb[i].offset += (size_t) accum_change;
5389 
5390                         /* Set the member type pointer (for convenience) */
5391                         memb_type = dt->shared->u.compnd.memb[i].type;
5392 
5393                         /* Recurse if it's VL, compound, enum or array */
5394                         /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
5395                         if(memb_type->shared->force_conv && H5T_IS_COMPLEX(memb_type->shared->type)) {
5396                             /* Keep the old field size for later */
5397                             old_size = memb_type->shared->size;
5398 
5399                             /* Mark the VL, compound, enum or array type */
5400                             if((changed = H5T_set_loc(memb_type,f,loc)) < 0)
5401                                 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
5402                             if(changed > 0)
5403                                 ret_value = changed;
5404 
5405                             /* Check if the field changed size */
5406                             if(old_size != memb_type->shared->size) {
5407 
5408                                 /* Fail if the old_size is zero */
5409                                 if (0 == old_size)
5410                                     HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "old_size of zero would cause division by zero");
5411 
5412                                 /* Adjust the size of the member */
5413                                 dt->shared->u.compnd.memb[i].size = (dt->shared->u.compnd.memb[i].size*memb_type->shared->size)/old_size;
5414 
5415                                 /* Add that change to the accumulated size change */
5416                                 accum_change += (ssize_t) (memb_type->shared->size - old_size);
5417                             } /* end if */
5418                         } /* end if */
5419                     } /* end for */
5420 
5421                     /* Range check against datatype size */
5422                     if ((accum_change < 0) && ((ssize_t) dt->shared->size < accum_change))
5423                         HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype");
5424 
5425                     /* Apply the accumulated size change to the datatype */
5426                     dt->shared->size += (size_t) accum_change;
5427                 }
5428                 break;
5429 
5430             case H5T_VLEN: /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */
5431                 /* Recurse if it's VL, compound, enum or array */
5432                 /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
5433                 if(dt->shared->parent->shared->force_conv && H5T_IS_COMPLEX(dt->shared->parent->shared->type)) {
5434                     if((changed = H5T_set_loc(dt->shared->parent,f,loc)) < 0)
5435                         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
5436                     if(changed > 0)
5437                         ret_value = changed;
5438                 } /* end if */
5439 
5440                 /* Mark this VL sequence */
5441                 if((changed = H5T__vlen_set_loc(dt, f, loc)) < 0)
5442                     HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
5443                 if(changed > 0)
5444                     ret_value = changed;
5445                 break;
5446 
5447             case H5T_REFERENCE:
5448                 /* Only need to change location of object references */
5449                 if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) {
5450                     /* Mark this reference */
5451                     if(loc != dt->shared->u.atomic.u.r.loc) {
5452                         /* Set the location */
5453                         dt->shared->u.atomic.u.r.loc = loc;
5454 
5455                         /* Indicate that the location changed */
5456                         ret_value = TRUE;
5457                     } /* end if */
5458                 } /* end if */
5459                 break;
5460 
5461             case H5T_NO_CLASS:
5462             case H5T_INTEGER:
5463             case H5T_FLOAT:
5464             case H5T_TIME:
5465             case H5T_STRING:
5466             case H5T_BITFIELD:
5467             case H5T_OPAQUE:
5468             case H5T_ENUM:
5469             case H5T_NCLASSES:
5470             default:
5471                 break;
5472         } /* end switch */
5473     } /* end if */
5474 
5475 done:
5476     FUNC_LEAVE_NOAPI(ret_value)
5477 }   /* end H5T_set_loc() */
5478 
5479 
5480 /*-------------------------------------------------------------------------
5481  * Function:    H5T_is_relocatable
5482  *
5483  * Purpose:     Check if a datatype will change between disk and memory.
5484  *
5485  * Notes:       Currently, only variable-length and object references change
5486  *              between disk & memory (see cases where things are changed in
5487  *              the H5T_set_loc() code above).
5488  *
5489  * Return:
5490  *  One of two values on success:
5491  *      TRUE - If the location of any vlen types changed
5492  *      FALSE - If the location of any vlen types is the same
5493  *  <0 is returned on failure
5494  *
5495  * Programmer:  Quincey Koziol
5496  *              Thursday, June 24, 2004
5497  *
5498  *-------------------------------------------------------------------------
5499  */
5500 htri_t
H5T_is_relocatable(const H5T_t * dt)5501 H5T_is_relocatable(const H5T_t *dt)
5502 {
5503     htri_t ret_value = FALSE;
5504 
5505     FUNC_ENTER_NOAPI(FAIL)
5506 
5507     /* Sanity check */
5508     HDassert(dt);
5509 
5510     /* VL and reference datatypes are relocatable */
5511     if(H5T_detect_class(dt, H5T_VLEN, FALSE) || H5T_detect_class(dt, H5T_REFERENCE, FALSE))
5512         ret_value = TRUE;
5513 
5514 done:
5515     FUNC_LEAVE_NOAPI(ret_value)
5516 } /* end H5T_is_relocatable() */
5517 
5518 
5519 /*-------------------------------------------------------------------------
5520  * Function:    H5T_upgrade_version_cb
5521  *
5522  * Purpose:     H5T__visit callback to Upgrade the version of a datatype
5523  *              (if there's any benefit to doing so)
5524  *
5525  * Note:        The behavior below is tightly coupled with the "better"
5526  *              encodings for datatype messages in the datatype message
5527  *              encoding routine.
5528  *
5529  * Return:      Non-negative on success/Negative on failure
5530  *
5531  * Programmer:  Quincey Koziol
5532  *              Thursday, July 19, 2007
5533  *
5534  *-------------------------------------------------------------------------
5535  */
5536 static herr_t
H5T_upgrade_version_cb(H5T_t * dt,void * op_value)5537 H5T_upgrade_version_cb(H5T_t *dt, void *op_value)
5538 {
5539     FUNC_ENTER_NOAPI_NOINIT_NOERR
5540 
5541     /* Sanity check */
5542     HDassert(dt);
5543     HDassert(op_value);
5544 
5545     /* Special behavior for each type of datatype */
5546     switch(dt->shared->type) {
5547         case H5T_COMPOUND:
5548         case H5T_ARRAY:
5549         case H5T_ENUM:
5550             /* These types benefit from "upgrading" their version */
5551             if(*(unsigned *)op_value > dt->shared->version)
5552                 dt->shared->version = *(unsigned *)op_value;
5553             break;
5554 
5555         case H5T_VLEN:
5556             if(dt->shared->parent->shared->version > dt->shared->version)
5557                 dt->shared->version = dt->shared->parent->shared->version;
5558             break;
5559 
5560         case H5T_NO_CLASS:
5561         case H5T_INTEGER:
5562         case H5T_FLOAT:
5563         case H5T_TIME:
5564         case H5T_STRING:
5565         case H5T_BITFIELD:
5566         case H5T_OPAQUE:
5567         case H5T_REFERENCE:
5568         case H5T_NCLASSES:
5569         default:
5570             break;
5571     } /* end switch */
5572 
5573     FUNC_LEAVE_NOAPI(SUCCEED)
5574 } /* end H5T_upgrade_version_cb() */
5575 
5576 
5577 /*-------------------------------------------------------------------------
5578  * Function:    H5T__upgrade_version
5579  *
5580  * Purpose:     Upgrade the version of a datatype (if there's any benefit to
5581  *              doing so) and recursively apply to compound members and/or
5582  *              parent datatypes.
5583  *
5584  * Return:      Non-negative on success/Negative on failure
5585  *
5586  * Programmer:  Quincey Koziol
5587  *              Thursday, July 19, 2007
5588  *
5589  *-------------------------------------------------------------------------
5590  */
5591 herr_t
H5T__upgrade_version(H5T_t * dt,unsigned new_version)5592 H5T__upgrade_version(H5T_t *dt, unsigned new_version)
5593 {
5594     herr_t ret_value = SUCCEED;         /* Return value */
5595 
5596     FUNC_ENTER_PACKAGE
5597 
5598     /* Sanity check */
5599     HDassert(dt);
5600 
5601     /* Iterate over entire datatype, upgrading the version of components, if it's useful */
5602     if(H5T__visit(dt, (H5T_VISIT_SIMPLE | H5T_VISIT_COMPLEX_LAST), H5T_upgrade_version_cb, &new_version) < 0)
5603         HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "iteration to upgrade datatype encoding version failed")
5604 
5605 done:
5606     FUNC_LEAVE_NOAPI(ret_value)
5607 } /* end H5T__upgrade_version() */
5608 
5609 
5610 /*-------------------------------------------------------------------------
5611  * Function:    H5T_set_version
5612  *
5613  * Purpose:     Set the encoding for a datatype to the version indicated by
5614  *              the file's low bound if that is higher than the datatype's
5615  *              version.
5616  *
5617  * Return:      Non-negative on success/Negative on failure
5618  *
5619  * Programmer:  Vailin Choi; December 2017
5620  *
5621  *-------------------------------------------------------------------------
5622  */
5623 herr_t
H5T_set_version(H5F_t * f,H5T_t * dt)5624 H5T_set_version(H5F_t *f, H5T_t *dt)
5625 {
5626     unsigned vers;                  /* The version */
5627     herr_t ret_value = SUCCEED;     /* Return value */
5628 
5629     FUNC_ENTER_NOAPI(FAIL)
5630 
5631     /* Sanity check */
5632     HDassert(f);
5633     HDassert(dt);
5634 
5635     vers = H5O_dtype_ver_bounds[H5F_LOW_BOUND(f)];
5636     if(vers > dt->shared->version) {
5637         /* Upgrade the format version for the datatype */
5638         if(H5T__upgrade_version(dt, vers) < 0)
5639             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade datatype encoding")
5640     }
5641 
5642     /* Version bounds check */
5643     if(dt->shared->version > H5O_dtype_ver_bounds[H5F_HIGH_BOUND(f)])
5644         HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "Datatype version out of bounds")
5645 
5646 done:
5647     FUNC_LEAVE_NOAPI(ret_value)
5648 } /* end H5T_set_version() */
5649 
5650 
5651 /*-------------------------------------------------------------------------
5652  * Function:    H5T_patch_file
5653  *
5654  * Purpose:     Patch the top-level file pointers contained in dt to point
5655  *              to f, if dt is a committed type.  This is possible because
5656  *              the top-level file pointer can be closed out from under
5657  *              dt while dt is contained in the shared file's cache.
5658  *
5659  * Return:      SUCCEED
5660  *
5661  * Programmer:  Neil Fortner
5662  *              Thursday, July 14, 2011
5663  *
5664  *-------------------------------------------------------------------------
5665  */
5666 herr_t
H5T_patch_file(H5T_t * dt,H5F_t * f)5667 H5T_patch_file(H5T_t *dt, H5F_t *f)
5668 {
5669     herr_t ret_value = SUCCEED;
5670 
5671     FUNC_ENTER_NOAPI(FAIL)
5672 
5673     /* Sanity check */
5674     HDassert(dt);
5675     HDassert(f);
5676 
5677     if(H5T_STATE_OPEN == dt->shared->state || H5T_STATE_NAMED == dt->shared->state) {
5678         dt->oloc.file = f;
5679         dt->sh_loc.file = f;
5680     } /* end if */
5681 
5682 done:
5683     FUNC_LEAVE_NOAPI(ret_value)
5684 } /* end H5T_patch_file() */
5685 
5686 
5687 /*-------------------------------------------------------------------------
5688  * Function:    H5T_patch_vlen_file
5689  *
5690  * Purpose:     Patch the top-level file pointer contained in (dt->shared->u.vlen.f)
5691  *              to point to f.  This is possible because
5692  *              the top-level file pointer can be closed out from under
5693  *              dt while dt is contained in the shared file's cache.
5694  *
5695  * Return:      SUCCEED
5696  *
5697  *-------------------------------------------------------------------------
5698  */
5699 herr_t
H5T_patch_vlen_file(H5T_t * dt,H5F_t * f)5700 H5T_patch_vlen_file(H5T_t *dt, H5F_t *f)
5701 {
5702     FUNC_ENTER_NOAPI_NOINIT_NOERR
5703 
5704     /* Sanity check */
5705     HDassert(dt);
5706     HDassert(dt->shared);
5707     HDassert(f);
5708 
5709     if((dt->shared->type == H5T_VLEN) && dt->shared->u.vlen.f != f)
5710         dt->shared->u.vlen.f = f;
5711 
5712     FUNC_LEAVE_NOAPI(SUCCEED)
5713 } /* end H5T_patch_vlen_file() */
5714 
5715