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 #define H5O_PACKAGE /*suppress error about including H5Opkg */
15 #define H5T_PACKAGE /*prevent warning from including H5Tpkg */
16
17 #include "H5private.h" /* Generic Functions */
18 #include "H5Dprivate.h" /* Datasets */
19 #include "H5Eprivate.h" /* Error handling */
20 #include "H5Fprivate.h" /* Files */
21 #include "H5FLprivate.h" /* Free Lists */
22 #include "H5Gprivate.h" /* Groups */
23 #include "H5MMprivate.h" /* Memory management */
24 #include "H5Opkg.h" /* Object headers */
25 #include "H5Tpkg.h" /* Datatypes */
26 #include "H5VMprivate.h" /* Vectors and arrays */
27
28
29 /* PRIVATE PROTOTYPES */
30 static herr_t H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg);
31 static void *H5O_dtype_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
32 unsigned mesg_flags, unsigned *ioflags, size_t p_size, const uint8_t *p);
33 static void *H5O_dtype_copy(const void *_mesg, void *_dest);
34 static size_t H5O_dtype_size(const H5F_t *f, const void *_mesg);
35 static herr_t H5O_dtype_reset(void *_mesg);
36 static herr_t H5O_dtype_free(void *_mesg);
37 static herr_t H5O_dtype_set_share(void *_mesg, const H5O_shared_t *sh);
38 static htri_t H5O_dtype_can_share(const void *_mesg);
39 static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
40 hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
41 static void *H5O_dtype_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
42 void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
43 H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
44 static herr_t H5O_dtype_shared_post_copy_upd(const H5O_loc_t *src_oloc,
45 const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
46 H5O_copy_t *cpy_info);
47
48 static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
49 FILE * stream, int indent, int fwidth);
50
51 /* Set up & include shared message "interface" info */
52 #define H5O_SHARED_TYPE H5O_MSG_DTYPE
53 #define H5O_SHARED_DECODE H5O_dtype_shared_decode
54 #define H5O_SHARED_DECODE_REAL H5O_dtype_decode
55 #define H5O_SHARED_ENCODE H5O_dtype_shared_encode
56 #define H5O_SHARED_ENCODE_REAL H5O_dtype_encode
57 #define H5O_SHARED_SIZE H5O_dtype_shared_size
58 #define H5O_SHARED_SIZE_REAL H5O_dtype_size
59 #define H5O_SHARED_DELETE H5O_dtype_shared_delete
60 #undef H5O_SHARED_DELETE_REAL
61 #define H5O_SHARED_LINK H5O_dtype_shared_link
62 #undef H5O_SHARED_LINK_REAL
63 #define H5O_SHARED_COPY_FILE H5O_dtype_shared_copy_file
64 #define H5O_SHARED_COPY_FILE_REAL H5O_dtype_copy_file
65 #define H5O_SHARED_POST_COPY_FILE H5O_dtype_shared_post_copy_file
66 #undef H5O_SHARED_POST_COPY_FILE_REAL
67 #define H5O_SHARED_POST_COPY_FILE_UPD H5O_dtype_shared_post_copy_upd
68 #define H5O_SHARED_DEBUG H5O_dtype_shared_debug
69 #define H5O_SHARED_DEBUG_REAL H5O_dtype_debug
70 #include "H5Oshared.h" /* Shared Object Header Message Callbacks */
71
72 /* Macros to check for the proper version of a datatype */
73 #ifdef H5_STRICT_FORMAT_CHECKS
74 /* If the version is too low, give an error. No error if nochange is set
75 * because in that case we are either debugging or deleting the object header */
76 #define H5O_DTYPE_CHECK_VERSION(DT, VERS, MIN_VERS, IOF, CLASS, ERR) \
77 if(((VERS) < (MIN_VERS)) && !(*(IOF) & H5O_DECODEIO_NOCHANGE)) \
78 HGOTO_ERROR(H5E_DATATYPE, H5E_VERSION, ERR, "incorrect " CLASS " datatype version")
79 #else /* H5_STRICT_FORMAT_CHECKS */
80 /* If the version is too low and we are allowed to change the message, upgrade
81 * it and mark the object header as dirty */
82 #define H5O_DTYPE_CHECK_VERSION(DT, VERS, MIN_VERS, IOF, CLASS, ERR) \
83 if(((VERS) < (MIN_VERS)) && !(*(IOF) & H5O_DECODEIO_NOCHANGE)) { \
84 (VERS) = (MIN_VERS); \
85 if(H5T__upgrade_version((DT), (VERS)) < 0) \
86 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade " CLASS " encoding version") \
87 *(IOF) |= H5O_DECODEIO_DIRTY; \
88 } /* end if */
89 #endif /* H5_STRICT_FORMAT_CHECKS */
90
91 /* This message derives from H5O message class */
92 const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
93 H5O_DTYPE_ID, /* message id number */
94 "datatype", /* message name for debugging */
95 sizeof(H5T_t), /* native message size */
96 H5O_SHARE_IS_SHARABLE|H5O_SHARE_IN_OHDR, /* messages are sharable? */
97 H5O_dtype_shared_decode, /* decode message */
98 H5O_dtype_shared_encode, /* encode message */
99 H5O_dtype_copy, /* copy the native value */
100 H5O_dtype_shared_size, /* size of raw message */
101 H5O_dtype_reset, /* reset method */
102 H5O_dtype_free, /* free method */
103 H5O_dtype_shared_delete, /* file delete method */
104 H5O_dtype_shared_link, /* link method */
105 H5O_dtype_set_share, /* set share method */
106 H5O_dtype_can_share, /* can share method */
107 H5O_dtype_pre_copy_file, /* pre copy native value to file */
108 H5O_dtype_shared_copy_file, /* copy native value to file */
109 H5O_dtype_shared_post_copy_file, /* post copy native value to file */
110 NULL, /* get creation index */
111 NULL, /* set creation index */
112 H5O_dtype_shared_debug /* debug the message */
113 }};
114
115
116 /*-------------------------------------------------------------------------
117 * Function: H5O_dtype_decode_helper
118 *
119 * Purpose: Decodes a datatype
120 *
121 * Return: TRUE if we can upgrade the parent type's version even
122 * with strict format checks
123 * FALSE if we cannot
124 * Negative on failure
125 *
126 * Programmer: Robb Matzke
127 * Monday, December 8, 1997
128 *
129 *-------------------------------------------------------------------------
130 */
131 static htri_t
H5O_dtype_decode_helper(H5F_t * f,unsigned * ioflags,const uint8_t ** pp,H5T_t * dt)132 H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt)
133 {
134 unsigned flags, version;
135 unsigned i;
136 size_t z;
137 htri_t ret_value = FALSE; /* Return value */
138
139 FUNC_ENTER_NOAPI_NOINIT
140
141 /* check args */
142 HDassert(pp && *pp);
143 HDassert(dt && dt->shared);
144
145 /* Version, class & flags */
146 UINT32DECODE(*pp, flags);
147 version = (flags>>4) & 0x0f;
148 if(version < H5O_DTYPE_VERSION_1 || version > H5O_DTYPE_VERSION_3)
149 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "bad version number for datatype message")
150 dt->shared->version = version;
151 dt->shared->type = (H5T_class_t)(flags & 0x0f);
152 flags >>= 8;
153
154 /* Size */
155 UINT32DECODE(*pp, dt->shared->size);
156
157 switch(dt->shared->type) {
158 case H5T_INTEGER:
159 /*
160 * Integer types...
161 */
162 dt->shared->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE;
163 dt->shared->u.atomic.lsb_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO;
164 dt->shared->u.atomic.msb_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO;
165 dt->shared->u.atomic.u.i.sign = (flags & 0x8) ? H5T_SGN_2 : H5T_SGN_NONE;
166 UINT16DECODE(*pp, dt->shared->u.atomic.offset);
167 UINT16DECODE(*pp, dt->shared->u.atomic.prec);
168 break;
169
170 case H5T_FLOAT:
171 /*
172 * Floating-point types...
173 */
174 dt->shared->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE;
175 if(version >= H5O_DTYPE_VERSION_3) {
176 /* Unsupported byte order*/
177 if((flags & 0x40) && !(flags & 0x1))
178 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bad byte order for datatype message")
179
180 /* VAX order if both 1st and 6th bits are turned on*/
181 if(flags & 0x40)
182 dt->shared->u.atomic.order = H5T_ORDER_VAX;
183 } /* end if */
184 dt->shared->u.atomic.lsb_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO;
185 dt->shared->u.atomic.msb_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO;
186 dt->shared->u.atomic.u.f.pad = (flags & 0x8) ? H5T_PAD_ONE : H5T_PAD_ZERO;
187 switch((flags >> 4) & 0x03) {
188 case 0:
189 dt->shared->u.atomic.u.f.norm = H5T_NORM_NONE;
190 break;
191
192 case 1:
193 dt->shared->u.atomic.u.f.norm = H5T_NORM_MSBSET;
194 break;
195
196 case 2:
197 dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED;
198 break;
199
200 default:
201 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown floating-point normalization")
202 } /* end switch */
203 dt->shared->u.atomic.u.f.sign = (flags >> 8) & 0xff;
204 UINT16DECODE(*pp, dt->shared->u.atomic.offset);
205 UINT16DECODE(*pp, dt->shared->u.atomic.prec);
206 dt->shared->u.atomic.u.f.epos = *(*pp)++;
207 dt->shared->u.atomic.u.f.esize = *(*pp)++;
208 HDassert(dt->shared->u.atomic.u.f.esize > 0);
209 dt->shared->u.atomic.u.f.mpos = *(*pp)++;
210 dt->shared->u.atomic.u.f.msize = *(*pp)++;
211 HDassert(dt->shared->u.atomic.u.f.msize > 0);
212 UINT32DECODE(*pp, dt->shared->u.atomic.u.f.ebias);
213 break;
214
215 case H5T_TIME: /* Time datatypes */
216 dt->shared->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE;
217 UINT16DECODE(*pp, dt->shared->u.atomic.prec);
218 break;
219
220 case H5T_STRING:
221 /*
222 * Character string types...
223 */
224 dt->shared->u.atomic.order = H5T_ORDER_NONE;
225 dt->shared->u.atomic.prec = 8 * dt->shared->size;
226 dt->shared->u.atomic.offset = 0;
227 dt->shared->u.atomic.lsb_pad = H5T_PAD_ZERO;
228 dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO;
229
230 dt->shared->u.atomic.u.s.pad = (H5T_str_t)(flags & 0x0f);
231 dt->shared->u.atomic.u.s.cset = (H5T_cset_t)((flags >> 4) & 0x0f);
232 break;
233
234 case H5T_BITFIELD:
235 /*
236 * Bit fields...
237 */
238 dt->shared->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE;
239 dt->shared->u.atomic.lsb_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO;
240 dt->shared->u.atomic.msb_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO;
241 UINT16DECODE(*pp, dt->shared->u.atomic.offset);
242 UINT16DECODE(*pp, dt->shared->u.atomic.prec);
243 break;
244
245 case H5T_OPAQUE:
246 /*
247 * Opaque types...
248 */
249 z = flags & (H5T_OPAQUE_TAG_MAX - 1);
250 HDassert(0 == (z & 0x7)); /*must be aligned*/
251 if(NULL == (dt->shared->u.opaque.tag = (char *)H5MM_malloc(z + 1)))
252 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
253 HDmemcpy(dt->shared->u.opaque.tag, *pp, z);
254 dt->shared->u.opaque.tag[z] = '\0';
255 *pp += z;
256 break;
257
258 case H5T_COMPOUND:
259 {
260 unsigned offset_nbytes; /* Size needed to encode member offsets */
261 size_t max_memb_pos = 0; /* Maximum member covered, so far */
262 unsigned max_version = 0; /* Maximum member version */
263 hbool_t upgrade_to = 0; /* Version number we can "soft" upgrade to */
264 unsigned j;
265
266 /* Compute the # of bytes required to store a member offset */
267 offset_nbytes = H5VM_limit_enc_size((uint64_t)dt->shared->size);
268
269 /*
270 * Compound datatypes...
271 */
272 dt->shared->u.compnd.nmembs = flags & 0xffff;
273 if(dt->shared->u.compnd.nmembs == 0)
274 HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid number of members: %u", dt->shared->u.compnd.nmembs)
275 dt->shared->u.compnd.nalloc = dt->shared->u.compnd.nmembs;
276 dt->shared->u.compnd.memb = (H5T_cmemb_t *)H5MM_calloc(dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t));
277 dt->shared->u.compnd.memb_size = 0;
278 if(NULL == dt->shared->u.compnd.memb)
279 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed")
280 for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
281 unsigned ndims = 0; /* Number of dimensions of the array field */
282 htri_t can_upgrade; /* Whether we can upgrade this type's version */
283 hsize_t dim[H5O_LAYOUT_NDIMS]; /* Dimensions of the array */
284 H5T_t *array_dt; /* Temporary pointer to the array datatype */
285 H5T_t *temp_type; /* Temporary pointer to the field's datatype */
286
287 /* Decode the field name */
288 dt->shared->u.compnd.memb[i].name = H5MM_xstrdup((const char *)*pp);
289
290 /* Version 3 of the datatype message eliminated the padding to multiple of 8 bytes */
291 if(version >= H5O_DTYPE_VERSION_3)
292 /* Advance past name, including null terminator */
293 *pp += HDstrlen((const char *)*pp) + 1;
294 else
295 /* Advance multiple of 8 w/ null terminator */
296 *pp += ((HDstrlen((const char *)*pp) + 8) / 8) * 8;
297
298 /* Decode the field offset */
299 /* (starting with version 3 of the datatype message, use the minimum # of bytes required) */
300 if(version >= H5O_DTYPE_VERSION_3)
301 UINT32DECODE_VAR(*pp, dt->shared->u.compnd.memb[i].offset, offset_nbytes)
302 else
303 UINT32DECODE(*pp, dt->shared->u.compnd.memb[i].offset)
304
305 /* Older versions of the library allowed a field to have
306 * intrinsic 'arrayness'. Newer versions of the library
307 * use the separate array datatypes. */
308 if(version == H5O_DTYPE_VERSION_1) {
309 /* Decode the number of dimensions */
310 ndims = *(*pp)++;
311
312 /* Check that ndims is valid */
313 if(ndims > 4)
314 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid number of dimensions for array")
315
316 *pp += 3; /*reserved bytes */
317
318 /* Skip dimension permutation */
319 *pp += 4;
320
321 /* Skip reserved bytes */
322 *pp += 4;
323
324 /* Decode array dimension sizes */
325 for(j = 0; j < 4; j++)
326 UINT32DECODE(*pp, dim[j]);
327 } /* end if */
328
329 /* Allocate space for the field's datatype */
330 if(NULL == (temp_type = H5T__alloc()))
331 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
332
333 /* Decode the field's datatype information */
334 if((can_upgrade = H5O_dtype_decode_helper(f, ioflags, pp, temp_type)) < 0) {
335 for(j = 0; j <= i; j++)
336 H5MM_xfree(dt->shared->u.compnd.memb[j].name);
337 H5MM_xfree(dt->shared->u.compnd.memb);
338 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode member type")
339 } /* end if */
340
341 /* Upgrade the version if we can and it is necessary */
342 if(can_upgrade && temp_type->shared->version > version) {
343 upgrade_to = temp_type->shared->version;
344
345 /* Pass "can_upgrade" flag down to parent type */
346 ret_value = TRUE;
347 } /* end if */
348
349 /* Go create the array datatype now, for older versions of the datatype message */
350 if(version == H5O_DTYPE_VERSION_1) {
351 /* Check if this member is an array field */
352 if(ndims > 0) {
353 /* Create the array datatype for the field */
354 if((array_dt = H5T__array_create(temp_type, ndims, dim)) == NULL) {
355 for(j = 0; j <= i; j++)
356 H5MM_xfree(dt->shared->u.compnd.memb[j].name);
357 H5MM_xfree(dt->shared->u.compnd.memb);
358 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create array datatype")
359 } /* end if */
360
361 /* Close the base type for the array */
362 H5T_close(temp_type);
363
364 /* Make the array type the type that is set for the field */
365 temp_type = array_dt;
366
367 /* Reset array version if NOCHANGE is specified (i.e. h5debug) */
368 if(*ioflags & H5O_DECODEIO_NOCHANGE)
369 temp_type->shared->version = H5O_DTYPE_VERSION_1;
370 else {
371 /* Otherwise upgrade the compound version */
372 if(upgrade_to < temp_type->shared->version)
373 upgrade_to = temp_type->shared->version;
374
375 /* Set the return value to indicate that we should freely
376 * upgrade parent types */
377 ret_value = TRUE;
378 } /* end else */
379 } /* end if */
380 } /* end if */
381
382 /* Keep track of the maximum member version found */
383 if(temp_type->shared->version > max_version)
384 max_version = temp_type->shared->version;
385
386 /*
387 * Set the "force conversion" flag if VL datatype fields exist in this
388 * type or any component types
389 */
390 if(temp_type->shared->force_conv == TRUE)
391 dt->shared->force_conv = TRUE;
392
393 /* Member size */
394 dt->shared->u.compnd.memb[i].size = temp_type->shared->size;
395 dt->shared->u.compnd.memb_size += temp_type->shared->size;
396
397 /* Set the field datatype (finally :-) */
398 dt->shared->u.compnd.memb[i].type = temp_type;
399
400 /* Check if this field overlaps with a prior field */
401 /* (probably indicates that the file is corrupt) */
402 if(i > 0 && dt->shared->u.compnd.memb[i].offset < max_memb_pos) {
403 for(j = 0; j < i; j++)
404 if(dt->shared->u.compnd.memb[i].offset >= dt->shared->u.compnd.memb[j].offset
405 && dt->shared->u.compnd.memb[i].offset < (dt->shared->u.compnd.memb[j].offset + dt->shared->u.compnd.memb[j].size))
406 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "member overlaps with previous member")
407 } /* end if */
408
409 /* Update the maximum member position covered */
410 max_memb_pos = MAX(max_memb_pos, (dt->shared->u.compnd.memb[i].offset + dt->shared->u.compnd.memb[i].size));
411 } /* end for */
412
413 /* Check if the compound type is packed */
414 H5T__update_packed(dt);
415
416 /* Upgrade the compound if requested */
417 if(version < upgrade_to) {
418 version = upgrade_to;
419 if(H5T__upgrade_version(dt, upgrade_to) < 0)
420 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade compound encoding version")
421 /* We won't mark the message dirty since there were no
422 * errors in the file, simply type versions that we will no
423 * longer encode. */
424 } /* end if */
425
426 /* Check that no member of this compound has a version greater
427 * than the compound itself. */
428 H5O_DTYPE_CHECK_VERSION(dt, version, max_version, ioflags, "compound", FAIL)
429 }
430 break;
431
432 case H5T_REFERENCE: /* Reference datatypes... */
433 dt->shared->u.atomic.order = H5T_ORDER_NONE;
434 dt->shared->u.atomic.prec = 8 * dt->shared->size;
435 dt->shared->u.atomic.offset = 0;
436 dt->shared->u.atomic.lsb_pad = H5T_PAD_ZERO;
437 dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO;
438
439 /* Set reference type */
440 dt->shared->u.atomic.u.r.rtype = (H5R_type_t)(flags & 0x0f);
441
442 /* Set extra information for object references, so the hobj_ref_t gets swizzled correctly */
443 if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) {
444 /* Mark location this type as undefined for now. The caller function should
445 * decide the location. */
446 dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC;
447
448 /* This type needs conversion */
449 dt->shared->force_conv = TRUE;
450 } /* end if */
451 break;
452
453 case H5T_ENUM:
454 /*
455 * Enumeration datatypes...
456 */
457 dt->shared->u.enumer.nmembs = dt->shared->u.enumer.nalloc = flags & 0xffff;
458 if(NULL == (dt->shared->parent = H5T__alloc()))
459 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
460 if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0)
461 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent datatype")
462
463 /* Check if the parent of this enum has a version greater than the
464 * enum itself. */
465 H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version,
466 ioflags, "enum", FAIL)
467
468 if(NULL == (dt->shared->u.enumer.name = (char **)H5MM_calloc(dt->shared->u.enumer.nalloc * sizeof(char*))) ||
469 NULL == (dt->shared->u.enumer.value = (uint8_t *)H5MM_calloc(dt->shared->u.enumer.nalloc * dt->shared->parent->shared->size)))
470 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
471
472 /* Names */
473 for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
474 dt->shared->u.enumer.name[i] = H5MM_xstrdup((const char*)*pp);
475
476 /* Version 3 of the datatype message eliminated the padding to multiple of 8 bytes */
477 if(version >= H5O_DTYPE_VERSION_3)
478 /* Advance past name, including null terminator */
479 *pp += HDstrlen((const char *)*pp) + 1;
480 else
481 /* Advance multiple of 8 w/ null terminator */
482 *pp += ((HDstrlen((const char *)*pp) + 8) / 8) * 8;
483 } /* end for */
484
485 /* Values */
486 HDmemcpy(dt->shared->u.enumer.value, *pp,
487 dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size);
488 *pp += dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size;
489 break;
490
491 case H5T_VLEN: /* Variable length datatypes... */
492 /* Set the type of VL information, either sequence or string */
493 dt->shared->u.vlen.type = (H5T_vlen_type_t)(flags & 0x0f);
494 if(dt->shared->u.vlen.type == H5T_VLEN_STRING) {
495 dt->shared->u.vlen.pad = (H5T_str_t)((flags >> 4) & 0x0f);
496 dt->shared->u.vlen.cset = (H5T_cset_t)((flags >> 8) & 0x0f);
497 } /* end if */
498
499 /* Decode base type of VL information */
500 if(NULL == (dt->shared->parent = H5T__alloc()))
501 HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed")
502 if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0)
503 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type")
504
505 /* Check if the parent of this vlen has a version greater than the
506 * vlen itself. */
507 H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version,
508 ioflags, "vlen", FAIL)
509
510 dt->shared->force_conv=TRUE;
511
512 /* Mark location this type as undefined for now. The caller function should
513 * decide the location. */
514 if(H5T_set_loc(dt, f, H5T_LOC_BADLOC) < 0)
515 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
516 break;
517
518 case H5T_ARRAY: /* Array datatypes */
519 /* Decode the number of dimensions */
520 dt->shared->u.array.ndims = *(*pp)++;
521
522 /* Double-check the number of dimensions */
523 if(dt->shared->u.array.ndims > H5S_MAX_RANK)
524 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "too many dimensions for array datatype")
525
526 /* Skip reserved bytes, if version has them */
527 if(version < H5O_DTYPE_VERSION_3)
528 *pp += 3;
529
530 /* Decode array dimension sizes & compute number of elements */
531 for(i = 0, dt->shared->u.array.nelem = 1; i < (unsigned)dt->shared->u.array.ndims; i++) {
532 UINT32DECODE(*pp, dt->shared->u.array.dim[i]);
533 dt->shared->u.array.nelem *= dt->shared->u.array.dim[i];
534 } /* end for */
535
536 /* Skip array dimension permutations, if version has them */
537 if(version < H5O_DTYPE_VERSION_3)
538 *pp += dt->shared->u.array.ndims * 4;
539
540 /* Decode base type of array */
541 if(NULL == (dt->shared->parent = H5T__alloc()))
542 HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed")
543 if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0)
544 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode array parent type")
545
546 /* Check if the parent of this array has a version greater than the
547 * array itself. */
548 H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version,
549 ioflags, "array", FAIL)
550
551 /* There should be no array datatypes with version < 2. */
552 H5O_DTYPE_CHECK_VERSION(dt, version, H5O_DTYPE_VERSION_2, ioflags,
553 "array", FAIL)
554
555 /*
556 * Set the "force conversion" flag if a VL base datatype is used or
557 * or if any components of the base datatype are VL types.
558 */
559 if(dt->shared->parent->shared->force_conv == TRUE)
560 dt->shared->force_conv = TRUE;
561 break;
562
563 case H5T_NO_CLASS:
564 case H5T_NCLASSES:
565 default:
566 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown datatype class found")
567 } /* end switch */
568
569 done:
570 if(ret_value < 0) {
571 if(dt != NULL) {
572 if(dt->shared != NULL)
573 dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
574 dt = H5FL_FREE(H5T_t, dt);
575 } /* end if */
576 } /* end if */
577
578 FUNC_LEAVE_NOAPI(ret_value)
579 } /* end H5O_dtype_decode_helper() */
580
581
582 /*-------------------------------------------------------------------------
583 * Function: H5O_dtype_encode_helper
584 *
585 * Purpose: Encodes a datatype.
586 *
587 * Note: When changing the format of a datatype (or adding a new one),
588 * remember to change the upgrade version callback
589 * (H5T_upgrade_version_cb).
590 *
591 * Return: Non-negative on success/Negative on failure
592 *
593 * Programmer: Robb Matzke
594 * Monday, December 8, 1997
595 *
596 *-------------------------------------------------------------------------
597 */
598 static herr_t
H5O_dtype_encode_helper(const H5F_t * f,uint8_t ** pp,const H5T_t * dt)599 H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
600 {
601 unsigned flags = 0;
602 uint8_t *hdr = (uint8_t *)*pp;
603 unsigned i;
604 size_t n, z;
605 herr_t ret_value = SUCCEED; /* Return value */
606
607 FUNC_ENTER_NOAPI_NOINIT
608
609 /* check args */
610 HDassert(pp && *pp);
611 HDassert(dt);
612
613 /* skip the type and class bit-field for now */
614 *pp += 4;
615 UINT32ENCODE(*pp, dt->shared->size);
616
617 switch(dt->shared->type) {
618 case H5T_INTEGER:
619 /*
620 * Integer datatypes...
621 */
622 switch (dt->shared->u.atomic.order) {
623 case H5T_ORDER_LE:
624 break; /*nothing */
625
626 case H5T_ORDER_BE:
627 flags |= 0x01;
628 break;
629
630 case H5T_ORDER_ERROR:
631 case H5T_ORDER_VAX:
632 case H5T_ORDER_MIXED:
633 case H5T_ORDER_NONE:
634 default:
635 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "byte order is not supported in file format yet")
636 } /* end switch */
637
638 switch (dt->shared->u.atomic.lsb_pad) {
639 case H5T_PAD_ZERO:
640 break; /*nothing */
641
642 case H5T_PAD_ONE:
643 flags |= 0x02;
644 break;
645
646 case H5T_PAD_ERROR:
647 case H5T_PAD_BACKGROUND:
648 case H5T_NPAD:
649 default:
650 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
651 } /* end switch */
652
653 switch (dt->shared->u.atomic.msb_pad) {
654 case H5T_PAD_ZERO:
655 break; /*nothing */
656
657 case H5T_PAD_ERROR:
658 case H5T_PAD_BACKGROUND:
659 case H5T_NPAD:
660 case H5T_PAD_ONE:
661 flags |= 0x04;
662 break;
663
664 default:
665 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
666 } /* end switch */
667
668 switch (dt->shared->u.atomic.u.i.sign) {
669 case H5T_SGN_NONE:
670 break; /*nothing */
671
672 case H5T_SGN_2:
673 flags |= 0x08;
674 break;
675
676 case H5T_SGN_ERROR:
677 case H5T_NSGN:
678 default:
679 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "sign scheme is not supported in file format yet")
680 } /* end switch */
681
682 UINT16ENCODE(*pp, dt->shared->u.atomic.offset);
683 UINT16ENCODE(*pp, dt->shared->u.atomic.prec);
684 break;
685
686 case H5T_FLOAT:
687 /*
688 * Floating-point types...
689 */
690 switch (dt->shared->u.atomic.order) {
691 case H5T_ORDER_LE:
692 break; /*nothing*/
693
694 case H5T_ORDER_BE:
695 flags |= 0x01;
696 break;
697
698 case H5T_ORDER_VAX: /*turn on 1st and 6th (reserved before adding VAX) bits*/
699 flags |= 0x41;
700 HDassert(dt->shared->version >= H5O_DTYPE_VERSION_3);
701 break;
702
703 case H5T_ORDER_MIXED:
704 case H5T_ORDER_ERROR:
705 case H5T_ORDER_NONE:
706 default:
707 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "byte order is not supported in file format yet")
708 } /* end switch */
709
710 switch (dt->shared->u.atomic.lsb_pad) {
711 case H5T_PAD_ZERO:
712 break; /*nothing */
713
714 case H5T_PAD_ONE:
715 flags |= 0x02;
716 break;
717
718 case H5T_PAD_ERROR:
719 case H5T_PAD_BACKGROUND:
720 case H5T_NPAD:
721 default:
722 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
723 } /* end switch */
724
725 switch (dt->shared->u.atomic.msb_pad) {
726 case H5T_PAD_ZERO:
727 break; /*nothing */
728
729 case H5T_PAD_ONE:
730 flags |= 0x04;
731 break;
732
733 case H5T_PAD_ERROR:
734 case H5T_PAD_BACKGROUND:
735 case H5T_NPAD:
736 default:
737 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
738 } /* end switch */
739
740 switch (dt->shared->u.atomic.u.f.pad) {
741 case H5T_PAD_ZERO:
742 break; /*nothing */
743
744 case H5T_PAD_ONE:
745 flags |= 0x08;
746 break;
747
748 case H5T_PAD_ERROR:
749 case H5T_PAD_BACKGROUND:
750 case H5T_NPAD:
751 default:
752 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
753 } /* end switch */
754
755 switch (dt->shared->u.atomic.u.f.norm) {
756 case H5T_NORM_NONE:
757 break; /*nothing */
758
759 case H5T_NORM_MSBSET:
760 flags |= 0x10;
761 break;
762
763 case H5T_NORM_IMPLIED:
764 flags |= 0x20;
765 break;
766
767 case H5T_NORM_ERROR:
768 default:
769 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "normalization scheme is not supported in file format yet")
770 } /* end switch */
771
772 flags = (unsigned)(flags | ((dt->shared->u.atomic.u.f.sign << 8) & 0xff00));
773 UINT16ENCODE(*pp, dt->shared->u.atomic.offset);
774 UINT16ENCODE(*pp, dt->shared->u.atomic.prec);
775 HDassert(dt->shared->u.atomic.u.f.epos <= 255);
776 *(*pp)++ = (uint8_t)(dt->shared->u.atomic.u.f.epos);
777 HDassert(dt->shared->u.atomic.u.f.esize <= 255);
778 *(*pp)++ = (uint8_t)(dt->shared->u.atomic.u.f.esize);
779 HDassert(dt->shared->u.atomic.u.f.mpos <= 255);
780 *(*pp)++ = (uint8_t)(dt->shared->u.atomic.u.f.mpos);
781 HDassert(dt->shared->u.atomic.u.f.msize <= 255);
782 *(*pp)++ = (uint8_t)(dt->shared->u.atomic.u.f.msize);
783 UINT32ENCODE(*pp, dt->shared->u.atomic.u.f.ebias);
784 break;
785
786 case H5T_TIME: /* Time datatypes... */
787 switch (dt->shared->u.atomic.order) {
788 case H5T_ORDER_LE:
789 break; /*nothing */
790
791 case H5T_ORDER_BE:
792 flags |= 0x01;
793 break;
794
795 case H5T_ORDER_VAX:
796 case H5T_ORDER_MIXED:
797 case H5T_ORDER_ERROR:
798 case H5T_ORDER_NONE:
799 default:
800 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "byte order is not supported in file format yet")
801 } /* end switch */
802 UINT16ENCODE(*pp, dt->shared->u.atomic.prec);
803 break;
804
805 case H5T_STRING:
806 /*
807 * Character string types... (not fully implemented)
808 */
809 HDassert(dt->shared->u.atomic.order == H5T_ORDER_NONE);
810 HDassert(dt->shared->u.atomic.prec == 8 * dt->shared->size);
811 HDassert(dt->shared->u.atomic.offset == 0);
812 HDassert(dt->shared->u.atomic.lsb_pad == H5T_PAD_ZERO);
813 HDassert(dt->shared->u.atomic.msb_pad == H5T_PAD_ZERO);
814
815 flags = (unsigned)(flags | (dt->shared->u.atomic.u.s.pad & 0x0f));
816 flags = (unsigned)(flags | ((((unsigned)dt->shared->u.atomic.u.s.cset) & 0x0f) << 4));
817 break;
818
819 case H5T_BITFIELD:
820 /*
821 * Bitfield datatypes...
822 */
823 switch (dt->shared->u.atomic.order) {
824 case H5T_ORDER_LE:
825 break; /*nothing */
826
827 case H5T_ORDER_BE:
828 flags |= 0x01;
829 break;
830
831 case H5T_ORDER_VAX:
832 case H5T_ORDER_MIXED:
833 case H5T_ORDER_ERROR:
834 case H5T_ORDER_NONE:
835 default:
836 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "byte order is not supported in file format yet")
837 } /* end switch */
838
839 switch (dt->shared->u.atomic.lsb_pad) {
840 case H5T_PAD_ZERO:
841 break; /*nothing */
842
843 case H5T_PAD_ONE:
844 flags |= 0x02;
845 break;
846
847 case H5T_PAD_ERROR:
848 case H5T_PAD_BACKGROUND:
849 case H5T_NPAD:
850 default:
851 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
852 } /* end switch */
853
854 switch (dt->shared->u.atomic.msb_pad) {
855 case H5T_PAD_ZERO:
856 break; /*nothing */
857
858 case H5T_PAD_ONE:
859 flags |= 0x04;
860 break;
861
862 case H5T_PAD_ERROR:
863 case H5T_PAD_BACKGROUND:
864 case H5T_NPAD:
865 default:
866 HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "bit padding is not supported in file format yet")
867 } /* end switch */
868
869 UINT16ENCODE(*pp, dt->shared->u.atomic.offset);
870 UINT16ENCODE(*pp, dt->shared->u.atomic.prec);
871 break;
872
873 case H5T_OPAQUE:
874 /*
875 * Opaque datatypes... The tag is stored in a field which is a
876 * multiple of eight characters and null padded (not necessarily
877 * null terminated).
878 */
879 {
880 size_t aligned;
881
882 z = HDstrlen(dt->shared->u.opaque.tag);
883 aligned = (z + 7) & (H5T_OPAQUE_TAG_MAX - 8);
884 flags = (unsigned)(flags | aligned);
885 HDmemcpy(*pp, dt->shared->u.opaque.tag, MIN(z,aligned));
886 for(n = MIN(z, aligned); n < aligned; n++)
887 (*pp)[n] = 0;
888 *pp += aligned;
889 }
890 break;
891
892 case H5T_COMPOUND:
893 {
894 unsigned offset_nbytes; /* Size needed to encode member offsets */
895
896 /* Compute the # of bytes required to store a member offset */
897 offset_nbytes = H5VM_limit_enc_size((uint64_t)dt->shared->size);
898
899 /*
900 * Compound datatypes...
901 */
902 flags = dt->shared->u.compnd.nmembs & 0xffff;
903 for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
904 /* Sanity check */
905 /* (compound datatypes w/array members must be encoded w/version >= 2) */
906 HDassert(dt->shared->u.compnd.memb[i].type->shared->type != H5T_ARRAY || dt->shared->version >= H5O_DTYPE_VERSION_2);
907
908 /* Check that the version is at least as great as the member */
909 HDassert(dt->shared->version >= dt->shared->u.compnd.memb[i].type->shared->version);
910
911 /* Name */
912 HDstrcpy((char*)(*pp), dt->shared->u.compnd.memb[i].name);
913
914 /* Version 3 of the datatype message removed the padding to multiple of 8 bytes */
915 n = HDstrlen(dt->shared->u.compnd.memb[i].name);
916 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
917 *pp += n + 1;
918 else {
919 /* Pad name to multiple of 8 bytes */
920 for(z = n + 1; z % 8; z++)
921 (*pp)[z] = '\0';
922 *pp += z;
923 } /* end if */
924
925 /* Member offset */
926 /* (starting with version 3 of the datatype message, use the minimum # of bytes required) */
927 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
928 UINT32ENCODE_VAR(*pp, (uint32_t)dt->shared->u.compnd.memb[i].offset, offset_nbytes)
929 else
930 UINT32ENCODE(*pp, dt->shared->u.compnd.memb[i].offset)
931
932 /* If we don't have any array fields, write out the old style
933 * member information, for better backward compatibility
934 * Write out all zeros for the array information, though...
935 */
936 if(dt->shared->version == H5O_DTYPE_VERSION_1) {
937 unsigned j;
938
939 /* Dimensionality */
940 *(*pp)++ = 0;
941
942 /* Reserved */
943 *(*pp)++ = 0;
944 *(*pp)++ = 0;
945 *(*pp)++ = 0;
946
947 /* Dimension permutation */
948 UINT32ENCODE(*pp, 0);
949
950 /* Reserved */
951 UINT32ENCODE(*pp, 0);
952
953 /* Dimensions */
954 for(j = 0; j < 4; j++)
955 UINT32ENCODE(*pp, 0);
956 } /* end if */
957
958 /* Subtype */
959 if(H5O_dtype_encode_helper(f, pp, dt->shared->u.compnd.memb[i].type) < 0)
960 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode member type")
961 } /* end for */
962 }
963 break;
964
965 case H5T_REFERENCE:
966 flags |= (dt->shared->u.atomic.u.r.rtype & 0x0f);
967 break;
968
969 case H5T_ENUM:
970 /* Check that the version is at least as great as the parent */
971 HDassert(dt->shared->version >= dt->shared->parent->shared->version);
972
973 /*
974 * Enumeration datatypes...
975 */
976 flags = dt->shared->u.enumer.nmembs & 0xffff;
977
978 /* Parent type */
979 if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0)
980 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode parent datatype")
981
982 /* Names, each a multiple of eight bytes */
983 for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
984 /* Name */
985 HDstrcpy((char*)(*pp), dt->shared->u.enumer.name[i]);
986
987 /* Version 3 of the datatype message removed the padding to multiple of 8 bytes */
988 n = HDstrlen(dt->shared->u.enumer.name[i]);
989 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
990 *pp += n + 1;
991 else {
992 /* Pad to multiple of 8 bytes */
993 for(z = n + 1; z % 8; z++)
994 (*pp)[z] = '\0';
995 *pp += z;
996 } /* end for */
997 } /* end for */
998
999 /* Values */
1000 HDmemcpy(*pp, dt->shared->u.enumer.value, dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size);
1001 *pp += dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size;
1002 break;
1003
1004 case H5T_VLEN: /* Variable length datatypes... */
1005 /* Check that the version is at least as great as the parent */
1006 HDassert(dt->shared->version >= dt->shared->parent->shared->version);
1007
1008 flags |= (dt->shared->u.vlen.type & 0x0f);
1009 if(dt->shared->u.vlen.type == H5T_VLEN_STRING) {
1010 flags = (unsigned)(flags | (((unsigned)dt->shared->u.vlen.pad & 0x0f) << 4));
1011 flags = (unsigned)(flags | (((unsigned)dt->shared->u.vlen.cset & 0x0f) << 8));
1012 } /* end if */
1013
1014 /* Encode base type of VL information */
1015 if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0)
1016 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type")
1017 break;
1018
1019 case H5T_ARRAY: /* Array datatypes */
1020 /* Double-check the number of dimensions */
1021 HDassert(dt->shared->u.array.ndims <= H5S_MAX_RANK);
1022
1023 /* Check that the version is valid */
1024 HDassert(dt->shared->version >= H5O_DTYPE_VERSION_2);
1025
1026 /* Check that the version is at least as great as the parent */
1027 HDassert(dt->shared->version >= dt->shared->parent->shared->version);
1028
1029 /* Encode the number of dimensions */
1030 HDassert(dt->shared->u.array.ndims <= UCHAR_MAX);
1031 *(*pp)++ = (uint8_t)dt->shared->u.array.ndims;
1032
1033 /* Drop this information for Version 3 of the format */
1034 if(dt->shared->version < H5O_DTYPE_VERSION_3) {
1035 /* Reserved */
1036 *(*pp)++ = '\0';
1037 *(*pp)++ = '\0';
1038 *(*pp)++ = '\0';
1039 } /* end if */
1040
1041 /* Encode array dimensions */
1042 for(i = 0; i < (unsigned)dt->shared->u.array.ndims; i++)
1043 UINT32ENCODE(*pp, dt->shared->u.array.dim[i]);
1044
1045 /* Drop this information for Version 3 of the format */
1046 if(dt->shared->version < H5O_DTYPE_VERSION_3) {
1047 /* Encode 'fake' array dimension permutations */
1048 for(i = 0; i < (unsigned)dt->shared->u.array.ndims; i++)
1049 UINT32ENCODE(*pp, i);
1050 } /* end if */
1051
1052 /* Encode base type of array's information */
1053 if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0)
1054 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type")
1055 break;
1056
1057 case H5T_NO_CLASS:
1058 case H5T_NCLASSES:
1059 default:
1060 /*nothing */
1061 break;
1062 } /* end switch */
1063
1064 /* Encode the type's class, version and bit field */
1065 *hdr++ = (uint8_t)(((unsigned)(dt->shared->type) & 0x0f) | (dt->shared->version << 4));
1066 *hdr++ = (uint8_t)((flags >> 0) & 0xff);
1067 *hdr++ = (uint8_t)((flags >> 8) & 0xff);
1068 *hdr++ = (uint8_t)((flags >> 16) & 0xff);
1069
1070 done:
1071 FUNC_LEAVE_NOAPI(ret_value)
1072 } /* end H5O_dtype_encode_helper() */
1073
1074
1075 /*--------------------------------------------------------------------------
1076 NAME
1077 H5O_dtype_decode
1078 PURPOSE
1079 Decode a message and return a pointer to a memory struct
1080 with the decoded information
1081 USAGE
1082 void *H5O_dtype_decode(f, dxpl_id, mesg_flags, p)
1083 H5F_t *f; IN: pointer to the HDF5 file struct
1084 hid_t dxpl_id; IN: DXPL for any I/O
1085 unsigned mesg_flags; IN: Message flags to influence decoding
1086 const uint8 *p; IN: the raw information buffer
1087 RETURNS
1088 Pointer to the new message in native order on success, NULL on failure
1089 DESCRIPTION
1090 This function decodes the "raw" disk form of a simple datatype message
1091 into a struct in memory native format. The struct is allocated within this
1092 function using malloc() and is returned to the caller.
1093 --------------------------------------------------------------------------*/
1094 static void *
H5O_dtype_decode(H5F_t * f,hid_t H5_ATTR_UNUSED dxpl_id,H5O_t H5_ATTR_UNUSED * open_oh,unsigned H5_ATTR_UNUSED mesg_flags,unsigned * ioflags,size_t H5_ATTR_UNUSED p_size,const uint8_t * p)1095 H5O_dtype_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
1096 unsigned *ioflags/*in,out*/, size_t H5_ATTR_UNUSED p_size, const uint8_t *p)
1097 {
1098 H5T_t *dt = NULL;
1099 void *ret_value; /* Return value */
1100
1101 FUNC_ENTER_NOAPI_NOINIT
1102
1103 /* check args */
1104 HDassert(p);
1105
1106 /* Allocate datatype message */
1107 if(NULL == (dt = H5T__alloc()))
1108 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
1109
1110 /* Perform actual decode of message */
1111 if(H5O_dtype_decode_helper(f, ioflags, &p, dt) < 0)
1112 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type")
1113
1114 /* Set return value */
1115 ret_value = dt;
1116
1117 done:
1118 FUNC_LEAVE_NOAPI(ret_value)
1119 } /* end H5O_dtype_decode() */
1120
1121
1122 /*--------------------------------------------------------------------------
1123 NAME
1124 H5O_dtype_encode
1125 PURPOSE
1126 Encode a simple datatype message
1127 USAGE
1128 herr_t H5O_dtype_encode(f, raw_size, p, mesg)
1129 H5F_t *f; IN: pointer to the HDF5 file struct
1130 size_t raw_size; IN: size of the raw information buffer
1131 const uint8 *p; IN: the raw information buffer
1132 const void *mesg; IN: Pointer to the simple datatype struct
1133 RETURNS
1134 Non-negative on success/Negative on failure
1135 DESCRIPTION
1136 This function encodes the native memory form of the simple datatype
1137 message in the "raw" disk form.
1138 --------------------------------------------------------------------------*/
1139 static herr_t
H5O_dtype_encode(H5F_t * f,uint8_t * p,const void * mesg)1140 H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg)
1141 {
1142 const H5T_t *dt = (const H5T_t *) mesg;
1143 herr_t ret_value = SUCCEED; /* Return value */
1144
1145 FUNC_ENTER_NOAPI_NOINIT
1146
1147 /* check args */
1148 HDassert(f);
1149 HDassert(p);
1150 HDassert(dt);
1151
1152 /* encode */
1153 if(H5O_dtype_encode_helper(f, &p, dt) < 0)
1154 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode type")
1155
1156 done:
1157 FUNC_LEAVE_NOAPI(ret_value)
1158 } /* end H5O_dtype_encode() */
1159
1160
1161 /*--------------------------------------------------------------------------
1162 NAME
1163 H5O_dtype_copy
1164 PURPOSE
1165 Copies a message from MESG to DEST, allocating DEST if necessary.
1166 USAGE
1167 void *H5O_dtype_copy(mesg, dest)
1168 const void *mesg; IN: Pointer to the source simple datatype
1169 struct
1170 const void *dest; IN: Pointer to the destination simple
1171 datatype struct
1172 RETURNS
1173 Pointer to DEST on success, NULL on failure
1174 DESCRIPTION
1175 This function copies a native (memory) simple datatype message,
1176 allocating the destination structure if necessary.
1177 --------------------------------------------------------------------------*/
1178 static void *
H5O_dtype_copy(const void * _src,void * _dst)1179 H5O_dtype_copy(const void *_src, void *_dst)
1180 {
1181 const H5T_t *src = (const H5T_t *) _src;
1182 H5T_t *dst;
1183 void *ret_value; /* Return value */
1184
1185 FUNC_ENTER_NOAPI_NOINIT
1186
1187 /* check args */
1188 HDassert(src);
1189
1190 /* Copy */
1191 if(NULL == (dst = H5T_copy(src, H5T_COPY_ALL)))
1192 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't copy type")
1193
1194 /* Was result already allocated? */
1195 if(_dst) {
1196 *((H5T_t *) _dst) = *dst;
1197 dst = H5FL_FREE(H5T_t, dst);
1198 dst = (H5T_t *) _dst;
1199 } /* end if */
1200
1201 /* Set return value */
1202 ret_value = dst;
1203
1204 done:
1205 FUNC_LEAVE_NOAPI(ret_value)
1206 } /* end H5O_dtype_copy() */
1207
1208
1209 /*--------------------------------------------------------------------------
1210 NAME
1211 H5O_dtype_size
1212 PURPOSE
1213 Return the raw message size in bytes
1214 USAGE
1215 void *H5O_dtype_size(f, mesg)
1216 H5F_t *f; IN: pointer to the HDF5 file struct
1217 const void *mesg; IN: Pointer to the source simple datatype struct
1218 RETURNS
1219 Size of message on success, 0 on failure
1220 DESCRIPTION
1221 This function returns the size of the raw simple datatype message on
1222 success. (Not counting the message type or size fields, only the data
1223 portion of the message). It doesn't take into account alignment.
1224 --------------------------------------------------------------------------*/
1225 static size_t
H5O_dtype_size(const H5F_t * f,const void * _mesg)1226 H5O_dtype_size(const H5F_t *f, const void *_mesg)
1227 {
1228 const H5T_t *dt = (const H5T_t *)_mesg;
1229 unsigned u; /* Local index variable */
1230 size_t ret_value;
1231
1232 FUNC_ENTER_NOAPI_NOINIT_NOERR
1233
1234 HDassert(f);
1235 HDassert(dt);
1236
1237 /* Set the common size information */
1238 ret_value = 4 + /* Type, class & flags */
1239 4; /* Size of datatype */
1240
1241 /* Add in the property field length for each datatype class */
1242 switch(dt->shared->type) {
1243 case H5T_INTEGER:
1244 ret_value += 4;
1245 break;
1246
1247 case H5T_FLOAT:
1248 ret_value += 12;
1249 break;
1250
1251 case H5T_TIME:
1252 ret_value += 2;
1253 break;
1254
1255 case H5T_BITFIELD:
1256 ret_value += 4;
1257 break;
1258
1259 case H5T_OPAQUE:
1260 ret_value += (HDstrlen(dt->shared->u.opaque.tag) + 7) & (H5T_OPAQUE_TAG_MAX - 8);
1261 break;
1262
1263 case H5T_COMPOUND:
1264 {
1265 unsigned offset_nbytes; /* Size needed to encode member offsets */
1266
1267 /* Compute the # of bytes required to store a member offset */
1268 offset_nbytes = H5VM_limit_enc_size((uint64_t)dt->shared->size);
1269
1270 /* Compute the total size needed to encode compound datatype */
1271 for(u = 0; u < dt->shared->u.compnd.nmembs; u++) {
1272 size_t name_len; /* Length of field's name */
1273
1274 /* Get length of field's name */
1275 name_len = HDstrlen(dt->shared->u.compnd.memb[u].name);
1276
1277 /* Versions of the format >= 3 don't pad out the name */
1278 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
1279 ret_value += name_len + 1;
1280 else
1281 ret_value += ((name_len + 8) / 8) * 8;
1282
1283 /* Check for encoding array datatype or using the latest file format */
1284 /* (starting with version 3 of the datatype message, use the minimum # of bytes required) */
1285 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
1286 ret_value += offset_nbytes; /*member offset*/
1287 else if(dt->shared->version == H5O_DTYPE_VERSION_2)
1288 ret_value += 4; /*member offset*/
1289 else
1290 ret_value += 4 + /*member offset*/
1291 1 + /*dimensionality*/
1292 3 + /*reserved*/
1293 4 + /*permutation*/
1294 4 + /*reserved*/
1295 16; /*dimensions*/
1296 ret_value += H5O_dtype_size(f, dt->shared->u.compnd.memb[u].type);
1297 } /* end for */
1298 }
1299 break;
1300
1301 case H5T_ENUM:
1302 ret_value += H5O_dtype_size(f, dt->shared->parent);
1303 for(u = 0; u < dt->shared->u.enumer.nmembs; u++) {
1304 size_t name_len; /* Length of field's name */
1305
1306 /* Get length of field's name */
1307 name_len = HDstrlen(dt->shared->u.enumer.name[u]);
1308
1309 /* Versions of the format >= 3 don't pad out the name */
1310 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
1311 ret_value += name_len + 1;
1312 else
1313 ret_value += ((name_len + 8) / 8) * 8;
1314 } /* end for */
1315 ret_value += dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size;
1316 break;
1317
1318 case H5T_VLEN:
1319 ret_value += H5O_dtype_size(f, dt->shared->parent);
1320 break;
1321
1322 case H5T_ARRAY:
1323 ret_value += 1; /* ndims */
1324 if(dt->shared->version < H5O_DTYPE_VERSION_3)
1325 ret_value += 3; /* reserved bytes*/
1326 ret_value += 4 * dt->shared->u.array.ndims; /* dimensions */
1327 if(dt->shared->version < H5O_DTYPE_VERSION_3)
1328 ret_value += 4 * dt->shared->u.array.ndims; /* dimension permutations */
1329 ret_value += H5O_dtype_size(f, dt->shared->parent);
1330 break;
1331
1332 case H5T_NO_CLASS:
1333 case H5T_STRING:
1334 case H5T_REFERENCE:
1335 case H5T_NCLASSES:
1336 default:
1337 /*no properties */
1338 break;
1339 } /* end switch */
1340
1341 FUNC_LEAVE_NOAPI(ret_value)
1342 } /* H5O_dtype_size() */
1343
1344
1345 /*-------------------------------------------------------------------------
1346 * Function: H5O_dtype_reset
1347 *
1348 * Purpose: Frees resources within a message, but doesn't free
1349 * the message itself.
1350 *
1351 * Return: Non-negative on success/Negative on failure
1352 *
1353 * Programmer: Robb Matzke
1354 * Tuesday, December 9, 1997
1355 *
1356 * Modifications:
1357 *
1358 *-------------------------------------------------------------------------
1359 */
1360 static herr_t
H5O_dtype_reset(void * _mesg)1361 H5O_dtype_reset(void *_mesg)
1362 {
1363 H5T_t *dt = (H5T_t *) _mesg;
1364
1365 FUNC_ENTER_NOAPI_NOINIT_NOERR
1366
1367 if(dt)
1368 H5T__free(dt);
1369
1370 FUNC_LEAVE_NOAPI(SUCCEED)
1371 } /* end H5O_dtype_reset() */
1372
1373
1374 /*-------------------------------------------------------------------------
1375 * Function: H5O_dtype_free
1376 *
1377 * Purpose: Free's the message
1378 *
1379 * Return: Non-negative on success/Negative on failure
1380 *
1381 * Programmer: Quincey Koziol
1382 * Thursday, March 30, 2000
1383 *
1384 * Modifications:
1385 *
1386 *-------------------------------------------------------------------------
1387 */
1388 static herr_t
H5O_dtype_free(void * mesg)1389 H5O_dtype_free(void *mesg)
1390 {
1391 FUNC_ENTER_NOAPI_NOINIT_NOERR
1392
1393 HDassert(mesg);
1394
1395 ((H5T_t *) mesg)->shared = H5FL_FREE(H5T_shared_t, ((H5T_t *) mesg)->shared);
1396 mesg = H5FL_FREE(H5T_t, mesg);
1397
1398 FUNC_LEAVE_NOAPI(SUCCEED)
1399 } /* end H5O_dtype_free() */
1400
1401
1402 /*-------------------------------------------------------------------------
1403 * Function: H5O_dtype_set_share
1404 *
1405 * Purpose: Copies sharing information from SH into the message.
1406 *
1407 * Return: Non-negative on success/Negative on failure
1408 *
1409 * Programmer: Robb Matzke
1410 * Thursday, June 4, 1998
1411 *
1412 *-------------------------------------------------------------------------
1413 */
1414 static herr_t
H5O_dtype_set_share(void * _mesg,const H5O_shared_t * sh)1415 H5O_dtype_set_share(void *_mesg/*in,out*/, const H5O_shared_t *sh)
1416 {
1417 H5T_t *dt = (H5T_t *)_mesg;
1418 herr_t ret_value = SUCCEED;
1419
1420 FUNC_ENTER_NOAPI_NOINIT
1421
1422 HDassert(dt);
1423 HDassert(sh);
1424
1425 /* Make sure the shared message location is initialized, so that it
1426 * either has valid sharing information or is set to 0.
1427 */
1428 HDassert(sh->type <= H5O_SHARE_TYPE_HERE);
1429
1430 /* Make sure we're not sharing a committed type in the heap */
1431 HDassert(sh->type == H5O_SHARE_TYPE_COMMITTED ||
1432 (dt->shared->state != H5T_STATE_OPEN && dt->shared->state != H5T_STATE_NAMED));
1433
1434 /* Copy the shared information */
1435 if(H5O_set_shared(&(dt->sh_loc), sh) < 0)
1436 HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy shared message info")
1437
1438 /* If this is now a committed datatype, set its state properly. */
1439 if(sh->type == H5O_SHARE_TYPE_COMMITTED) {
1440 dt->shared->state = H5T_STATE_NAMED;
1441
1442 /* Set up the object location for the datatype also */
1443 dt->oloc.file = sh->file;
1444 dt->oloc.addr = sh->u.loc.oh_addr;;
1445 dt->oloc.holding_file = FALSE;
1446 } /* end if */
1447
1448 done:
1449 FUNC_LEAVE_NOAPI(ret_value)
1450 } /* end H5O_dtype_set_share() */
1451
1452
1453 /*-------------------------------------------------------------------------
1454 * Function: H5O_dtype_can_share
1455 *
1456 * Purpose: Determines if this datatype is allowed to be shared or
1457 * not. Immutable datatypes or datatypes that are already
1458 * shared cannot be shared (again).
1459 *
1460 * Return: TRUE if datatype can be shared
1461 * FALSE if datatype may not shared
1462 * Negative on failure
1463 *
1464 * Programmer: James Laird
1465 * Monday, October 16, 2006
1466 *
1467 *-------------------------------------------------------------------------
1468 */
1469 static htri_t
H5O_dtype_can_share(const void * _mesg)1470 H5O_dtype_can_share(const void *_mesg)
1471 {
1472 const H5T_t *mesg = (const H5T_t *)_mesg;
1473 htri_t tri_ret;
1474 htri_t ret_value = TRUE;
1475
1476 FUNC_ENTER_NOAPI_NOINIT
1477
1478 HDassert(mesg);
1479
1480 /* Don't share immutable datatypes */
1481 if((tri_ret = H5T_is_immutable(mesg)) > 0)
1482 HGOTO_DONE(FALSE)
1483 else if(tri_ret < 0)
1484 HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "can't tell if datatype is immutable")
1485
1486 /* Don't share committed datatypes */
1487 if((tri_ret = H5T_committed(mesg)) > 0)
1488 HGOTO_DONE(FALSE)
1489 else if(tri_ret < 0)
1490 HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "can't tell if datatype is shared")
1491
1492 done:
1493 FUNC_LEAVE_NOAPI(ret_value)
1494 } /* end H5O_dtype_can_share() */
1495
1496
1497 /*-------------------------------------------------------------------------
1498 * Function: H5O_dtype_pre_copy_file
1499 *
1500 * Purpose: Perform any necessary actions before copying message between
1501 * files
1502 *
1503 * Return: Success: Non-negative
1504 *
1505 * Failure: Negative
1506 *
1507 * Programmer: Quincey Koziol
1508 * November 21, 2005
1509 *
1510 *-------------------------------------------------------------------------
1511 */
1512 static herr_t
H5O_dtype_pre_copy_file(H5F_t * file_src,const void * mesg_src,hbool_t H5_ATTR_UNUSED * deleted,const H5O_copy_t H5_ATTR_UNUSED * cpy_info,void * _udata)1513 H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
1514 hbool_t H5_ATTR_UNUSED *deleted, const H5O_copy_t H5_ATTR_UNUSED *cpy_info,
1515 void *_udata)
1516 {
1517 const H5T_t *dt_src = (const H5T_t *)mesg_src; /* Source datatype */
1518 H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
1519 herr_t ret_value = SUCCEED; /* Return value */
1520
1521 FUNC_ENTER_NOAPI_NOINIT
1522
1523 /* check args */
1524 HDassert(file_src);
1525 HDassert(dt_src);
1526
1527 /* If the user data is non-NULL, assume we are copying a dataset
1528 * and check if we need to make a copy of the datatype for later in
1529 * the object copying process. (We currently only need to make a copy
1530 * of the datatype if it's a vlen or reference datatype, or if the layout
1531 * message is an early version, but since the layout information isn't
1532 * available here, we just make a copy in all situations)
1533 */
1534 if(udata) {
1535 /* Create a memory copy of the variable-length datatype */
1536 if(NULL == (udata->src_dtype = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
1537 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
1538
1539 /* Set the location of the source datatype to describe the disk form of the data */
1540 if(H5T_set_loc(udata->src_dtype, file_src, H5T_LOC_DISK) < 0)
1541 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
1542 } /* end if */
1543
1544 done:
1545 FUNC_LEAVE_NOAPI(ret_value)
1546 } /* end H5O_dtype_pre_copy_file() */
1547
1548
1549 /*-------------------------------------------------------------------------
1550 * Function: H5O_dtype_copy_file
1551 *
1552 * Purpose: Copy a native datatype message from one file to another.
1553 *
1554 * Return: Success: Native copy of message
1555 * Failure: NULL
1556 *
1557 * Programmer: James Laird
1558 * December 12, 2006
1559 *
1560 *-------------------------------------------------------------------------
1561 */
1562 static void *
H5O_dtype_copy_file(H5F_t H5_ATTR_UNUSED * file_src,const H5O_msg_class_t * mesg_type,void * native_src,H5F_t * file_dst,hbool_t H5_ATTR_UNUSED * recompute_size,H5O_copy_t H5_ATTR_UNUSED * cpy_info,void H5_ATTR_UNUSED * udata,hid_t H5_ATTR_UNUSED dxpl_id)1563 H5O_dtype_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const H5O_msg_class_t *mesg_type,
1564 void *native_src, H5F_t *file_dst, hbool_t H5_ATTR_UNUSED *recompute_size,
1565 H5O_copy_t H5_ATTR_UNUSED *cpy_info, void H5_ATTR_UNUSED *udata, hid_t H5_ATTR_UNUSED dxpl_id)
1566 {
1567 H5T_t *dst_mesg; /* Destination datatype */
1568 void *ret_value; /* Return value */
1569
1570 FUNC_ENTER_NOAPI_NOINIT
1571
1572 /* Perform a normal copy of the object header message */
1573 if(NULL == (dst_mesg = (H5T_t *)H5O_dtype_copy(native_src, NULL)))
1574 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
1575
1576 /* The datatype will be in the new file; set its location. */
1577 if(H5T_set_loc(dst_mesg, file_dst, H5T_LOC_DISK) < 0)
1578 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to set location")
1579
1580 ret_value = dst_mesg;
1581
1582 done:
1583 if(NULL == ret_value)
1584 H5O_msg_free(mesg_type->id, dst_mesg);
1585 FUNC_LEAVE_NOAPI(ret_value)
1586 } /* end H5O_dtype_copy_file() */
1587
1588
1589 /*-------------------------------------------------------------------------
1590 * Function: H5O_dtype_shared_post_copy_upd
1591 *
1592 * Purpose: Update a message after the shared message operations
1593 * during the post-copy loop
1594 *
1595 * Return: Non-negative on success/Negative on failure
1596 *
1597 * Programmer: Neil Fortner
1598 * November 8, 2011
1599 *
1600 *-------------------------------------------------------------------------
1601 */
1602 static herr_t
H5O_dtype_shared_post_copy_upd(const H5O_loc_t H5_ATTR_UNUSED * src_oloc,const void H5_ATTR_UNUSED * mesg_src,H5O_loc_t H5_ATTR_UNUSED * dst_oloc,void * mesg_dst,hid_t H5_ATTR_UNUSED dxpl_id,H5O_copy_t H5_ATTR_UNUSED * cpy_info)1603 H5O_dtype_shared_post_copy_upd(const H5O_loc_t H5_ATTR_UNUSED *src_oloc,
1604 const void H5_ATTR_UNUSED *mesg_src, H5O_loc_t H5_ATTR_UNUSED *dst_oloc, void *mesg_dst,
1605 hid_t H5_ATTR_UNUSED dxpl_id, H5O_copy_t H5_ATTR_UNUSED *cpy_info)
1606 {
1607 H5T_t *dt_dst = (H5T_t *)mesg_dst; /* Destination datatype */
1608
1609 FUNC_ENTER_NOAPI_NOINIT_NOERR
1610
1611 if(dt_dst->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
1612 HDassert(H5T_committed(dt_dst));
1613 dt_dst->oloc.file = dt_dst->sh_loc.file;
1614 dt_dst->oloc.addr = dt_dst->sh_loc.u.loc.oh_addr;
1615 } /* end if */
1616 else
1617 HDassert(!H5T_committed(dt_dst));
1618
1619 FUNC_LEAVE_NOAPI(SUCCEED)
1620 } /* end H5O_dtype_shared_post_copy_upd */
1621
1622
1623 /*--------------------------------------------------------------------------
1624 NAME
1625 H5O_dtype_debug
1626 PURPOSE
1627 Prints debugging information for a message
1628 USAGE
1629 void *H5O_dtype_debug(f, mesg, stream, indent, fwidth)
1630 H5F_t *f; IN: pointer to the HDF5 file struct
1631 const void *mesg; IN: Pointer to the source simple datatype
1632 struct
1633 FILE *stream; IN: Pointer to the stream for output data
1634 int indent; IN: Amount to indent information by
1635 int fwidth; IN: Field width (?)
1636 RETURNS
1637 Non-negative on success/Negative on failure
1638 DESCRIPTION
1639 This function prints debugging output to the stream passed as a
1640 parameter.
1641 --------------------------------------------------------------------------*/
1642 static herr_t
H5O_dtype_debug(H5F_t * f,hid_t dxpl_id,const void * mesg,FILE * stream,int indent,int fwidth)1643 H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
1644 int indent, int fwidth)
1645 {
1646 const H5T_t *dt = (const H5T_t*)mesg;
1647 const char *s;
1648 char buf[256];
1649 unsigned i;
1650 size_t k;
1651
1652 FUNC_ENTER_NOAPI_NOINIT_NOERR
1653
1654 /* check args */
1655 HDassert(f);
1656 HDassert(dt);
1657 HDassert(stream);
1658 HDassert(indent >= 0);
1659 HDassert(fwidth >= 0);
1660
1661 switch (dt->shared->type) {
1662 case H5T_INTEGER:
1663 s = "integer";
1664 break;
1665
1666 case H5T_FLOAT:
1667 s = "floating-point";
1668 break;
1669
1670 case H5T_TIME:
1671 s = "date and time";
1672 break;
1673
1674 case H5T_STRING:
1675 s = "text string";
1676 break;
1677
1678 case H5T_BITFIELD:
1679 s = "bit field";
1680 break;
1681
1682 case H5T_OPAQUE:
1683 s = "opaque";
1684 break;
1685
1686 case H5T_COMPOUND:
1687 s = "compound";
1688 break;
1689
1690 case H5T_REFERENCE:
1691 s = "reference";
1692 break;
1693
1694 case H5T_ENUM:
1695 s = "enum";
1696 break;
1697
1698 case H5T_ARRAY:
1699 s = "array";
1700 break;
1701
1702 case H5T_VLEN:
1703 s = "vlen";
1704 break;
1705
1706 case H5T_NO_CLASS:
1707 case H5T_NCLASSES:
1708 default:
1709 sprintf(buf, "H5T_CLASS_%d", (int)(dt->shared->type));
1710 s = buf;
1711 break;
1712 } /* end switch */
1713 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1714 "Type class:",
1715 s);
1716
1717 fprintf(stream, "%*s%-*s %lu byte%s\n", indent, "", fwidth,
1718 "Size:",
1719 (unsigned long)(dt->shared->size), 1 == dt->shared->size ? "" : "s");
1720
1721 fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1722 "Version:", dt->shared->version);
1723
1724 if (H5T_COMPOUND == dt->shared->type) {
1725 fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1726 "Number of members:",
1727 dt->shared->u.compnd.nmembs);
1728 for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
1729 sprintf(buf, "Member %u:", i);
1730 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1731 buf,
1732 dt->shared->u.compnd.memb[i].name);
1733 fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0, fwidth-3),
1734 "Byte offset:",
1735 (unsigned long)(dt->shared->u.compnd.memb[i].offset));
1736 H5O_dtype_debug(f, dxpl_id, dt->shared->u.compnd.memb[i].type, stream,
1737 indent + 3, MAX(0, fwidth - 3));
1738 }
1739 } else if(H5T_ENUM == dt->shared->type) {
1740 fprintf(stream, "%*s%s\n", indent, "", "Base type:");
1741 H5O_dtype_debug(f, dxpl_id, dt->shared->parent, stream, indent+3, MAX(0, fwidth-3));
1742 fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1743 "Number of members:",
1744 dt->shared->u.enumer.nmembs);
1745 for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
1746 sprintf(buf, "Member %u:", i);
1747 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1748 buf,
1749 dt->shared->u.enumer.name[i]);
1750 fprintf(stream, "%*s%-*s 0x", indent, "", fwidth,
1751 "Raw bytes of value:");
1752 for(k = 0; k < dt->shared->parent->shared->size; k++)
1753 fprintf(stream, "%02x",
1754 dt->shared->u.enumer.value[i*dt->shared->parent->shared->size + k]);
1755 fprintf(stream, "\n");
1756 } /* end for */
1757
1758 } else if(H5T_OPAQUE == dt->shared->type) {
1759 fprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth,
1760 "Tag:", dt->shared->u.opaque.tag);
1761 } else if(H5T_REFERENCE == dt->shared->type) {
1762 fprintf(stream, "%*s%-*s\n", indent, "", fwidth,
1763 "Fix dumping reference types!");
1764 } else if(H5T_STRING == dt->shared->type) {
1765 switch(dt->shared->u.atomic.u.s.cset) {
1766 case H5T_CSET_ASCII:
1767 s = "ASCII";
1768 break;
1769
1770 case H5T_CSET_UTF8:
1771 s = "UTF-8";
1772 break;
1773
1774 case H5T_CSET_RESERVED_2:
1775 case H5T_CSET_RESERVED_3:
1776 case H5T_CSET_RESERVED_4:
1777 case H5T_CSET_RESERVED_5:
1778 case H5T_CSET_RESERVED_6:
1779 case H5T_CSET_RESERVED_7:
1780 case H5T_CSET_RESERVED_8:
1781 case H5T_CSET_RESERVED_9:
1782 case H5T_CSET_RESERVED_10:
1783 case H5T_CSET_RESERVED_11:
1784 case H5T_CSET_RESERVED_12:
1785 case H5T_CSET_RESERVED_13:
1786 case H5T_CSET_RESERVED_14:
1787 case H5T_CSET_RESERVED_15:
1788 sprintf(buf, "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.cset));
1789 s = buf;
1790 break;
1791
1792 case H5T_CSET_ERROR:
1793 default:
1794 sprintf(buf, "Unknown character set: %d", (int)(dt->shared->u.atomic.u.s.cset));
1795 s = buf;
1796 break;
1797 } /* end switch */
1798 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1799 "Character Set:",
1800 s);
1801
1802 switch(dt->shared->u.atomic.u.s.pad) {
1803 case H5T_STR_NULLTERM:
1804 s = "NULL Terminated";
1805 break;
1806
1807 case H5T_STR_NULLPAD:
1808 s = "NULL Padded";
1809 break;
1810
1811 case H5T_STR_SPACEPAD:
1812 s = "Space Padded";
1813 break;
1814
1815 case H5T_STR_RESERVED_3:
1816 case H5T_STR_RESERVED_4:
1817 case H5T_STR_RESERVED_5:
1818 case H5T_STR_RESERVED_6:
1819 case H5T_STR_RESERVED_7:
1820 case H5T_STR_RESERVED_8:
1821 case H5T_STR_RESERVED_9:
1822 case H5T_STR_RESERVED_10:
1823 case H5T_STR_RESERVED_11:
1824 case H5T_STR_RESERVED_12:
1825 case H5T_STR_RESERVED_13:
1826 case H5T_STR_RESERVED_14:
1827 case H5T_STR_RESERVED_15:
1828 sprintf(buf, "H5T_STR_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.pad));
1829 s = buf;
1830 break;
1831
1832 case H5T_STR_ERROR:
1833 default:
1834 sprintf(buf, "Unknown string padding: %d", (int)(dt->shared->u.atomic.u.s.pad));
1835 s = buf;
1836 break;
1837 } /* end switch */
1838 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1839 "String Padding:",
1840 s);
1841 } else if(H5T_VLEN == dt->shared->type) {
1842 switch(dt->shared->u.vlen.type) {
1843 case H5T_VLEN_SEQUENCE:
1844 s = "sequence";
1845 break;
1846
1847 case H5T_VLEN_STRING:
1848 s = "string";
1849 break;
1850
1851 case H5T_VLEN_BADTYPE:
1852 case H5T_VLEN_MAXTYPE:
1853 default:
1854 sprintf(buf, "H5T_VLEN_%d", dt->shared->u.vlen.type);
1855 s = buf;
1856 break;
1857 } /* end switch */
1858 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1859 "Vlen type:", s);
1860
1861 switch(dt->shared->u.vlen.loc) {
1862 case H5T_LOC_MEMORY:
1863 s = "memory";
1864 break;
1865
1866 case H5T_LOC_DISK:
1867 s = "disk";
1868 break;
1869
1870 case H5T_LOC_BADLOC:
1871 case H5T_LOC_MAXLOC:
1872 default:
1873 sprintf(buf, "H5T_LOC_%d", (int)dt->shared->u.vlen.loc);
1874 s = buf;
1875 break;
1876 } /* end switch */
1877 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1878 "Location:", s);
1879
1880 /* Extra information for VL-strings */
1881 if(dt->shared->u.vlen.type == H5T_VLEN_STRING) {
1882 switch(dt->shared->u.vlen.cset) {
1883 case H5T_CSET_ASCII:
1884 s = "ASCII";
1885 break;
1886
1887 case H5T_CSET_UTF8:
1888 s = "UTF-8";
1889 break;
1890
1891 case H5T_CSET_RESERVED_2:
1892 case H5T_CSET_RESERVED_3:
1893 case H5T_CSET_RESERVED_4:
1894 case H5T_CSET_RESERVED_5:
1895 case H5T_CSET_RESERVED_6:
1896 case H5T_CSET_RESERVED_7:
1897 case H5T_CSET_RESERVED_8:
1898 case H5T_CSET_RESERVED_9:
1899 case H5T_CSET_RESERVED_10:
1900 case H5T_CSET_RESERVED_11:
1901 case H5T_CSET_RESERVED_12:
1902 case H5T_CSET_RESERVED_13:
1903 case H5T_CSET_RESERVED_14:
1904 case H5T_CSET_RESERVED_15:
1905 sprintf(buf, "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.vlen.cset));
1906 s = buf;
1907 break;
1908
1909 case H5T_CSET_ERROR:
1910 default:
1911 sprintf(buf, "Unknown character set: %d", (int)(dt->shared->u.vlen.cset));
1912 s = buf;
1913 break;
1914 } /* end switch */
1915 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1916 "Character Set:",
1917 s);
1918
1919 switch(dt->shared->u.vlen.pad) {
1920 case H5T_STR_NULLTERM:
1921 s = "NULL Terminated";
1922 break;
1923
1924 case H5T_STR_NULLPAD:
1925 s = "NULL Padded";
1926 break;
1927
1928 case H5T_STR_SPACEPAD:
1929 s = "Space Padded";
1930 break;
1931
1932 case H5T_STR_RESERVED_3:
1933 case H5T_STR_RESERVED_4:
1934 case H5T_STR_RESERVED_5:
1935 case H5T_STR_RESERVED_6:
1936 case H5T_STR_RESERVED_7:
1937 case H5T_STR_RESERVED_8:
1938 case H5T_STR_RESERVED_9:
1939 case H5T_STR_RESERVED_10:
1940 case H5T_STR_RESERVED_11:
1941 case H5T_STR_RESERVED_12:
1942 case H5T_STR_RESERVED_13:
1943 case H5T_STR_RESERVED_14:
1944 case H5T_STR_RESERVED_15:
1945 sprintf(buf, "H5T_STR_RESERVED_%d", (int)(dt->shared->u.vlen.pad));
1946 s = buf;
1947 break;
1948
1949 case H5T_STR_ERROR:
1950 default:
1951 sprintf(buf, "Unknown string padding: %d", (int)(dt->shared->u.vlen.pad));
1952 s = buf;
1953 break;
1954 } /* end switch */
1955 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1956 "String Padding:",
1957 s);
1958 } /* end if */
1959 } else if(H5T_ARRAY == dt->shared->type) {
1960 fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1961 "Rank:",
1962 dt->shared->u.array.ndims);
1963 fprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Size:");
1964 for(i = 0; i < dt->shared->u.array.ndims; i++)
1965 fprintf(stream, "%s%u", (i ? ", " : ""), (unsigned)dt->shared->u.array.dim[i]);
1966 fprintf(stream, "}\n");
1967 fprintf(stream, "%*s%s\n", indent, "", "Base type:");
1968 H5O_dtype_debug(f, dxpl_id, dt->shared->parent, stream, indent + 3, MAX(0, fwidth - 3));
1969 } else {
1970 switch (dt->shared->u.atomic.order) {
1971 case H5T_ORDER_LE:
1972 s = "little endian";
1973 break;
1974
1975 case H5T_ORDER_BE:
1976 s = "big endian";
1977 break;
1978
1979 case H5T_ORDER_VAX:
1980 s = "VAX";
1981 break;
1982
1983 case H5T_ORDER_NONE:
1984 s = "none";
1985 break;
1986
1987 case H5T_ORDER_MIXED:
1988 s = "mixed";
1989 break;
1990
1991 case H5T_ORDER_ERROR:
1992 default:
1993 sprintf(buf, "H5T_ORDER_%d", dt->shared->u.atomic.order);
1994 s = buf;
1995 break;
1996 } /* end switch */
1997 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1998 "Byte order:",
1999 s);
2000
2001 fprintf(stream, "%*s%-*s %lu bit%s\n", indent, "", fwidth,
2002 "Precision:",
2003 (unsigned long)(dt->shared->u.atomic.prec),
2004 1==dt->shared->u.atomic.prec?"":"s");
2005
2006 fprintf(stream, "%*s%-*s %lu bit%s\n", indent, "", fwidth,
2007 "Offset:",
2008 (unsigned long)(dt->shared->u.atomic.offset),
2009 1==dt->shared->u.atomic.offset?"":"s");
2010
2011 switch (dt->shared->u.atomic.lsb_pad) {
2012 case H5T_PAD_ZERO:
2013 s = "zero";
2014 break;
2015
2016 case H5T_PAD_ONE:
2017 s = "one";
2018 break;
2019
2020 case H5T_PAD_BACKGROUND:
2021 s = "background";
2022 break;
2023
2024 case H5T_PAD_ERROR:
2025 case H5T_NPAD:
2026 default:
2027 s = "pad?";
2028 break;
2029 } /* end switch */
2030 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2031 "Low pad type:", s);
2032
2033 switch (dt->shared->u.atomic.msb_pad) {
2034 case H5T_PAD_ZERO:
2035 s = "zero";
2036 break;
2037
2038 case H5T_PAD_ONE:
2039 s = "one";
2040 break;
2041
2042 case H5T_PAD_BACKGROUND:
2043 s = "background";
2044 break;
2045
2046 case H5T_PAD_ERROR:
2047 case H5T_NPAD:
2048 default:
2049 s = "pad?";
2050 break;
2051 } /* end switch */
2052 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2053 "High pad type:", s);
2054
2055 if (H5T_FLOAT == dt->shared->type) {
2056 switch (dt->shared->u.atomic.u.f.pad) {
2057 case H5T_PAD_ZERO:
2058 s = "zero";
2059 break;
2060
2061 case H5T_PAD_ONE:
2062 s = "one";
2063 break;
2064
2065 case H5T_PAD_BACKGROUND:
2066 s = "background";
2067 break;
2068
2069 case H5T_PAD_ERROR:
2070 case H5T_NPAD:
2071 default:
2072 if (dt->shared->u.atomic.u.f.pad < 0)
2073 sprintf(buf, "H5T_PAD_%d", -(dt->shared->u.atomic.u.f.pad));
2074 else
2075 sprintf(buf, "bit-%d", dt->shared->u.atomic.u.f.pad);
2076 s = buf;
2077 break;
2078 } /* end switch */
2079 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2080 "Internal pad type:", s);
2081
2082 switch (dt->shared->u.atomic.u.f.norm) {
2083 case H5T_NORM_IMPLIED:
2084 s = "implied";
2085 break;
2086
2087 case H5T_NORM_MSBSET:
2088 s = "msb set";
2089 break;
2090
2091 case H5T_NORM_NONE:
2092 s = "none";
2093 break;
2094
2095 case H5T_NORM_ERROR:
2096 default:
2097 sprintf(buf, "H5T_NORM_%d", (int) (dt->shared->u.atomic.u.f.norm));
2098 s = buf;
2099 } /* end switch */
2100 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2101 "Normalization:", s);
2102
2103 fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2104 "Sign bit location:",
2105 (unsigned long) (dt->shared->u.atomic.u.f.sign));
2106
2107 fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2108 "Exponent location:",
2109 (unsigned long) (dt->shared->u.atomic.u.f.epos));
2110
2111 fprintf(stream, "%*s%-*s 0x%08lx\n", indent, "", fwidth,
2112 "Exponent bias:",
2113 (unsigned long) (dt->shared->u.atomic.u.f.ebias));
2114
2115 fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2116 "Exponent size:",
2117 (unsigned long) (dt->shared->u.atomic.u.f.esize));
2118
2119 fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2120 "Mantissa location:",
2121 (unsigned long) (dt->shared->u.atomic.u.f.mpos));
2122
2123 fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2124 "Mantissa size:",
2125 (unsigned long) (dt->shared->u.atomic.u.f.msize));
2126
2127 } else if (H5T_INTEGER == dt->shared->type) {
2128 switch (dt->shared->u.atomic.u.i.sign) {
2129 case H5T_SGN_NONE:
2130 s = "none";
2131 break;
2132
2133 case H5T_SGN_2:
2134 s = "2's comp";
2135 break;
2136
2137 case H5T_SGN_ERROR:
2138 case H5T_NSGN:
2139 default:
2140 sprintf(buf, "H5T_SGN_%d", (int) (dt->shared->u.atomic.u.i.sign));
2141 s = buf;
2142 break;
2143 } /* end switch */
2144 fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2145 "Sign scheme:", s);
2146 }
2147 }
2148
2149 FUNC_LEAVE_NOAPI(SUCCEED)
2150 } /* end H5O_dtype_debug() */
2151
2152