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