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 #include "H5Omodule.h" /* This source code file is part of the H5O module */
15 #define H5T_FRIEND /*prevent warning from including H5Tpkg */
16
17
18 #include "H5private.h" /* Generic Functions */
19 #include "H5Dprivate.h" /* Datasets */
20 #include "H5Eprivate.h" /* Error handling */
21 #include "H5Fprivate.h" /* Files */
22 #include "H5FLprivate.h" /* Free Lists */
23 #include "H5Gprivate.h" /* Groups */
24 #include "H5MMprivate.h" /* Memory management */
25 #include "H5Opkg.h" /* Object headers */
26 #include "H5Tpkg.h" /* Datatypes */
27 #include "H5VMprivate.h" /* Vectors and arrays */
28
29
30 /* PRIVATE PROTOTYPES */
31 static herr_t H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg);
32 static void *H5O_dtype_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags,
33 unsigned *ioflags, size_t p_size, const uint8_t *p);
34 static void *H5O_dtype_copy(const void *_mesg, void *_dest);
35 static size_t H5O_dtype_size(const H5F_t *f, const void *_mesg);
36 static herr_t H5O__dtype_reset(void *_mesg);
37 static herr_t H5O__dtype_free(void *_mesg);
38 static herr_t H5O_dtype_set_share(void *_mesg, const H5O_shared_t *sh);
39 static htri_t H5O_dtype_can_share(const void *_mesg);
40 static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
41 hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
42 static void *H5O__dtype_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
43 void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
44 H5O_copy_t *cpy_info, void *udata);
45 static herr_t H5O__dtype_shared_post_copy_upd(const H5O_loc_t *src_oloc,
46 const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
47 H5O_copy_t *cpy_info);
48 static herr_t H5O__dtype_debug(H5F_t *f, const void *_mesg, FILE * stream,
49 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 unsigned 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 (void)H5T_close_real(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, mesg_flags, p)
1083 H5F_t *f; IN: pointer to the HDF5 file struct
1084 unsigned mesg_flags; IN: Message flags to influence decoding
1085 const uint8 *p; IN: the raw information buffer
1086 RETURNS
1087 Pointer to the new message in native order on success, NULL on failure
1088 DESCRIPTION
1089 This function decodes the "raw" disk form of a simple datatype message
1090 into a struct in memory native format. The struct is allocated within this
1091 function using malloc() and is returned to the caller.
1092 --------------------------------------------------------------------------*/
1093 static void *
H5O_dtype_decode(H5F_t * f,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)1094 H5O_dtype_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
1095 unsigned *ioflags/*in,out*/, size_t H5_ATTR_UNUSED p_size, const uint8_t *p)
1096 {
1097 H5T_t *dt = NULL;
1098 void *ret_value = NULL; /* Return value */
1099
1100 FUNC_ENTER_NOAPI_NOINIT
1101
1102 /* check args */
1103 HDassert(p);
1104
1105 /* Allocate datatype message */
1106 if(NULL == (dt = H5T__alloc()))
1107 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
1108
1109 /* Perform actual decode of message */
1110 if(H5O_dtype_decode_helper(f, ioflags, &p, dt) < 0)
1111 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type")
1112
1113 /* Set return value */
1114 ret_value = dt;
1115
1116 done:
1117 FUNC_LEAVE_NOAPI(ret_value)
1118 } /* end H5O_dtype_decode() */
1119
1120
1121 /*--------------------------------------------------------------------------
1122 NAME
1123 H5O_dtype_encode
1124 PURPOSE
1125 Encode a simple datatype message
1126 USAGE
1127 herr_t H5O_dtype_encode(f, raw_size, p, mesg)
1128 H5F_t *f; IN: pointer to the HDF5 file struct
1129 size_t raw_size; IN: size of the raw information buffer
1130 const uint8 *p; IN: the raw information buffer
1131 const void *mesg; IN: Pointer to the simple datatype struct
1132 RETURNS
1133 Non-negative on success/Negative on failure
1134 DESCRIPTION
1135 This function encodes the native memory form of the simple datatype
1136 message in the "raw" disk form.
1137 --------------------------------------------------------------------------*/
1138 static herr_t
H5O_dtype_encode(H5F_t * f,uint8_t * p,const void * mesg)1139 H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg)
1140 {
1141 const H5T_t *dt = (const H5T_t *) mesg;
1142 herr_t ret_value = SUCCEED; /* Return value */
1143
1144 FUNC_ENTER_NOAPI_NOINIT
1145
1146 /* check args */
1147 HDassert(f);
1148 HDassert(p);
1149 HDassert(dt);
1150
1151 /* encode */
1152 if(H5O_dtype_encode_helper(f, &p, dt) < 0)
1153 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode type")
1154
1155 done:
1156 FUNC_LEAVE_NOAPI(ret_value)
1157 } /* end H5O_dtype_encode() */
1158
1159
1160 /*--------------------------------------------------------------------------
1161 NAME
1162 H5O_dtype_copy
1163 PURPOSE
1164 Copies a message from MESG to DEST, allocating DEST if necessary.
1165 USAGE
1166 void *H5O_dtype_copy(mesg, dest)
1167 const void *mesg; IN: Pointer to the source simple datatype
1168 struct
1169 const void *dest; IN: Pointer to the destination simple
1170 datatype struct
1171 RETURNS
1172 Pointer to DEST on success, NULL on failure
1173 DESCRIPTION
1174 This function copies a native (memory) simple datatype message,
1175 allocating the destination structure if necessary.
1176 --------------------------------------------------------------------------*/
1177 static void *
H5O_dtype_copy(const void * _src,void * _dst)1178 H5O_dtype_copy(const void *_src, void *_dst)
1179 {
1180 const H5T_t *src = (const H5T_t *) _src;
1181 H5T_t *dst;
1182 void *ret_value = NULL; /* Return value */
1183
1184 FUNC_ENTER_NOAPI_NOINIT
1185
1186 /* check args */
1187 HDassert(src);
1188
1189 /* Copy */
1190 if(NULL == (dst = H5T_copy(src, H5T_COPY_ALL)))
1191 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't copy type")
1192
1193 /* Was result already allocated? */
1194 if(_dst) {
1195 *((H5T_t *) _dst) = *dst;
1196 dst = H5FL_FREE(H5T_t, dst);
1197 dst = (H5T_t *) _dst;
1198 } /* end if */
1199
1200 /* Set return value */
1201 ret_value = dst;
1202
1203 done:
1204 FUNC_LEAVE_NOAPI(ret_value)
1205 } /* end H5O_dtype_copy() */
1206
1207
1208 /*--------------------------------------------------------------------------
1209 NAME
1210 H5O_dtype_size
1211 PURPOSE
1212 Return the raw message size in bytes
1213 USAGE
1214 void *H5O_dtype_size(f, mesg)
1215 H5F_t *f; IN: pointer to the HDF5 file struct
1216 const void *mesg; IN: Pointer to the source simple datatype struct
1217 RETURNS
1218 Size of message on success, 0 on failure
1219 DESCRIPTION
1220 This function returns the size of the raw simple datatype message on
1221 success. (Not counting the message type or size fields, only the data
1222 portion of the message). It doesn't take into account alignment.
1223 --------------------------------------------------------------------------*/
1224 static size_t
H5O_dtype_size(const H5F_t * f,const void * _mesg)1225 H5O_dtype_size(const H5F_t *f, const void *_mesg)
1226 {
1227 const H5T_t *dt = (const H5T_t *)_mesg;
1228 unsigned u; /* Local index variable */
1229 size_t ret_value = 0; /* Return value */
1230
1231 FUNC_ENTER_NOAPI_NOINIT_NOERR
1232
1233 HDassert(f);
1234 HDassert(dt);
1235
1236 /* Set the common size information */
1237 ret_value = 4 + /* Type, class & flags */
1238 4; /* Size of datatype */
1239
1240 /* Add in the property field length for each datatype class */
1241 switch(dt->shared->type) {
1242 case H5T_INTEGER:
1243 ret_value += 4;
1244 break;
1245
1246 case H5T_FLOAT:
1247 ret_value += 12;
1248 break;
1249
1250 case H5T_TIME:
1251 ret_value += 2;
1252 break;
1253
1254 case H5T_BITFIELD:
1255 ret_value += 4;
1256 break;
1257
1258 case H5T_OPAQUE:
1259 ret_value += (HDstrlen(dt->shared->u.opaque.tag) + 7) & (H5T_OPAQUE_TAG_MAX - 8);
1260 break;
1261
1262 case H5T_COMPOUND:
1263 {
1264 unsigned offset_nbytes; /* Size needed to encode member offsets */
1265
1266 /* Compute the # of bytes required to store a member offset */
1267 offset_nbytes = H5VM_limit_enc_size((uint64_t)dt->shared->size);
1268
1269 /* Compute the total size needed to encode compound datatype */
1270 for(u = 0; u < dt->shared->u.compnd.nmembs; u++) {
1271 size_t name_len; /* Length of field's name */
1272
1273 /* Get length of field's name */
1274 name_len = HDstrlen(dt->shared->u.compnd.memb[u].name);
1275
1276 /* Versions of the format >= 3 don't pad out the name */
1277 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
1278 ret_value += name_len + 1;
1279 else
1280 ret_value += ((name_len + 8) / 8) * 8;
1281
1282 /* Check for encoding array datatype or using the latest file format */
1283 /* (starting with version 3 of the datatype message, use the minimum # of bytes required) */
1284 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
1285 ret_value += offset_nbytes; /*member offset*/
1286 else if(dt->shared->version == H5O_DTYPE_VERSION_2)
1287 ret_value += 4; /*member offset*/
1288 else
1289 ret_value += 4 + /*member offset*/
1290 1 + /*dimensionality*/
1291 3 + /*reserved*/
1292 4 + /*permutation*/
1293 4 + /*reserved*/
1294 16; /*dimensions*/
1295 ret_value += H5O_dtype_size(f, dt->shared->u.compnd.memb[u].type);
1296 } /* end for */
1297 }
1298 break;
1299
1300 case H5T_ENUM:
1301 ret_value += H5O_dtype_size(f, dt->shared->parent);
1302 for(u = 0; u < dt->shared->u.enumer.nmembs; u++) {
1303 size_t name_len; /* Length of field's name */
1304
1305 /* Get length of field's name */
1306 name_len = HDstrlen(dt->shared->u.enumer.name[u]);
1307
1308 /* Versions of the format >= 3 don't pad out the name */
1309 if(dt->shared->version >= H5O_DTYPE_VERSION_3)
1310 ret_value += name_len + 1;
1311 else
1312 ret_value += ((name_len + 8) / 8) * 8;
1313 } /* end for */
1314 ret_value += dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size;
1315 break;
1316
1317 case H5T_VLEN:
1318 ret_value += H5O_dtype_size(f, dt->shared->parent);
1319 break;
1320
1321 case H5T_ARRAY:
1322 ret_value += 1; /* ndims */
1323 if(dt->shared->version < H5O_DTYPE_VERSION_3)
1324 ret_value += 3; /* reserved bytes*/
1325 ret_value += 4 * dt->shared->u.array.ndims; /* dimensions */
1326 if(dt->shared->version < H5O_DTYPE_VERSION_3)
1327 ret_value += 4 * dt->shared->u.array.ndims; /* dimension permutations */
1328 ret_value += H5O_dtype_size(f, dt->shared->parent);
1329 break;
1330
1331 case H5T_NO_CLASS:
1332 case H5T_STRING:
1333 case H5T_REFERENCE:
1334 case H5T_NCLASSES:
1335 default:
1336 /*no properties */
1337 break;
1338 } /* end switch */
1339
1340 FUNC_LEAVE_NOAPI(ret_value)
1341 } /* H5O_dtype_size() */
1342
1343
1344 /*-------------------------------------------------------------------------
1345 * Function: H5O__dtype_reset
1346 *
1347 * Purpose: Frees resources within a message, but doesn't free
1348 * the message itself.
1349 *
1350 * Return: Non-negative on success/Negative on failure
1351 *
1352 * Programmer: Robb Matzke
1353 * Tuesday, December 9, 1997
1354 *
1355 *-------------------------------------------------------------------------
1356 */
1357 static herr_t
H5O__dtype_reset(void * _mesg)1358 H5O__dtype_reset(void *_mesg)
1359 {
1360 H5T_t *dt = (H5T_t *) _mesg;
1361
1362 FUNC_ENTER_STATIC_NOERR
1363
1364 if(dt)
1365 H5T__free(dt);
1366
1367 FUNC_LEAVE_NOAPI(SUCCEED)
1368 } /* end H5O__dtype_reset() */
1369
1370
1371 /*-------------------------------------------------------------------------
1372 * Function: H5O__dtype_free
1373 *
1374 * Purpose: Frees the message
1375 *
1376 * Return: Non-negative on success/Negative on failure
1377 *
1378 * Programmer: Quincey Koziol
1379 * Thursday, March 30, 2000
1380 *
1381 *-------------------------------------------------------------------------
1382 */
1383 static herr_t
H5O__dtype_free(void * mesg)1384 H5O__dtype_free(void *mesg)
1385 {
1386 herr_t ret_value = SUCCEED; /* Return value */
1387
1388 FUNC_ENTER_STATIC
1389
1390 /* Sanity check */
1391 HDassert(mesg);
1392
1393 /* Release the datatype */
1394 if(H5T_close_real((H5T_t *)mesg) < 0)
1395 HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free datatype")
1396
1397 done:
1398 FUNC_LEAVE_NOAPI(ret_value)
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 if(H5O_loc_reset(&(dt->oloc)) < 0)
1444 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to reset location")
1445 dt->oloc.file = sh->file;
1446 dt->oloc.addr = sh->u.loc.oh_addr;
1447 } /* end if */
1448
1449 done:
1450 FUNC_LEAVE_NOAPI(ret_value)
1451 } /* end H5O_dtype_set_share() */
1452
1453
1454 /*-------------------------------------------------------------------------
1455 * Function: H5O_dtype_can_share
1456 *
1457 * Purpose: Determines if this datatype is allowed to be shared or
1458 * not. Immutable datatypes or datatypes that are already
1459 * shared cannot be shared (again).
1460 *
1461 * Return: TRUE if datatype can be shared
1462 * FALSE if datatype may not shared
1463 * Negative on failure
1464 *
1465 * Programmer: James Laird
1466 * Monday, October 16, 2006
1467 *
1468 *-------------------------------------------------------------------------
1469 */
1470 static htri_t
H5O_dtype_can_share(const void * _mesg)1471 H5O_dtype_can_share(const void *_mesg)
1472 {
1473 const H5T_t *mesg = (const H5T_t *)_mesg;
1474 htri_t tri_ret;
1475 htri_t ret_value = TRUE;
1476
1477 FUNC_ENTER_NOAPI_NOINIT
1478
1479 HDassert(mesg);
1480
1481 /* Don't share immutable datatypes */
1482 if((tri_ret = H5T_is_immutable(mesg)) > 0)
1483 HGOTO_DONE(FALSE)
1484 else if(tri_ret < 0)
1485 HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "can't tell if datatype is immutable")
1486
1487 /* Don't share committed datatypes */
1488 if((tri_ret = H5T_committed(mesg)) > 0)
1489 HGOTO_DONE(FALSE)
1490 else if(tri_ret < 0)
1491 HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "can't tell if datatype is shared")
1492
1493 done:
1494 FUNC_LEAVE_NOAPI(ret_value)
1495 } /* end H5O_dtype_can_share() */
1496
1497
1498 /*-------------------------------------------------------------------------
1499 * Function: H5O_dtype_pre_copy_file
1500 *
1501 * Purpose: Perform any necessary actions before copying message between
1502 * files
1503 *
1504 * Return: Success: Non-negative
1505 *
1506 * Failure: Negative
1507 *
1508 * Programmer: Quincey Koziol
1509 * November 21, 2005
1510 *
1511 *-------------------------------------------------------------------------
1512 */
1513 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 * cpy_info,void * _udata)1514 H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
1515 hbool_t H5_ATTR_UNUSED *deleted, const H5O_copy_t *cpy_info,
1516 void *_udata)
1517 {
1518 const H5T_t *dt_src = (const H5T_t *)mesg_src; /* Source datatype */
1519 H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
1520 herr_t ret_value = SUCCEED; /* Return value */
1521
1522 FUNC_ENTER_NOAPI_NOINIT
1523
1524 /* check args */
1525 HDassert(file_src);
1526 HDassert(dt_src);
1527 HDassert(cpy_info);
1528 HDassert(cpy_info->file_dst);
1529
1530 /* Check to ensure that the version of the message to be copied does not exceed
1531 the message version as indicated by the destination file's high bound */
1532 if(dt_src->shared->version > H5O_dtype_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)])
1533 HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "datatype message version out of bounds")
1534
1535 /* If the user data is non-NULL, assume we are copying a dataset
1536 * and check if we need to make a copy of the datatype for later in
1537 * the object copying process. (We currently only need to make a copy
1538 * of the datatype if it's a vlen or reference datatype, or if the layout
1539 * message is an early version, but since the layout information isn't
1540 * available here, we just make a copy in all situations)
1541 */
1542 if(udata) {
1543 /* Create a memory copy of the variable-length datatype */
1544 if(NULL == (udata->src_dtype = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
1545 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
1546
1547 /* Set the location of the source datatype to describe the disk form of the data */
1548 if(H5T_set_loc(udata->src_dtype, file_src, H5T_LOC_DISK) < 0)
1549 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
1550 } /* end if */
1551
1552 done:
1553 FUNC_LEAVE_NOAPI(ret_value)
1554 } /* end H5O_dtype_pre_copy_file() */
1555
1556
1557 /*-------------------------------------------------------------------------
1558 * Function: H5O__dtype_copy_file
1559 *
1560 * Purpose: Copy a native datatype message from one file to another.
1561 *
1562 * Return: Success: Native copy of message
1563 * Failure: NULL
1564 *
1565 * Programmer: James Laird
1566 * December 12, 2006
1567 *
1568 *-------------------------------------------------------------------------
1569 */
1570 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)1571 H5O__dtype_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const H5O_msg_class_t *mesg_type,
1572 void *native_src, H5F_t *file_dst, hbool_t H5_ATTR_UNUSED *recompute_size,
1573 H5O_copy_t H5_ATTR_UNUSED *cpy_info, void H5_ATTR_UNUSED *udata)
1574 {
1575 H5T_t *dst_mesg; /* Destination datatype */
1576 void *ret_value = NULL; /* Return value */
1577
1578 FUNC_ENTER_STATIC
1579
1580 /* Perform a normal copy of the object header message */
1581 if(NULL == (dst_mesg = (H5T_t *)H5O_dtype_copy(native_src, NULL)))
1582 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
1583
1584 /* The datatype will be in the new file; set its location. */
1585 if(H5T_set_loc(dst_mesg, file_dst, H5T_LOC_DISK) < 0)
1586 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to set location")
1587
1588 ret_value = dst_mesg;
1589
1590 done:
1591 if(NULL == ret_value)
1592 H5O_msg_free(mesg_type->id, dst_mesg);
1593
1594 FUNC_LEAVE_NOAPI(ret_value)
1595 } /* end H5O__dtype_copy_file() */
1596
1597
1598 /*-------------------------------------------------------------------------
1599 * Function: H5O__dtype_shared_post_copy_upd
1600 *
1601 * Purpose: Update a message after the shared message operations
1602 * during the post-copy loop
1603 *
1604 * Return: Non-negative on success/Negative on failure
1605 *
1606 * Programmer: Neil Fortner
1607 * November 8, 2011
1608 *
1609 *-------------------------------------------------------------------------
1610 */
1611 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,H5O_copy_t H5_ATTR_UNUSED * cpy_info)1612 H5O__dtype_shared_post_copy_upd(const H5O_loc_t H5_ATTR_UNUSED *src_oloc,
1613 const void H5_ATTR_UNUSED *mesg_src, H5O_loc_t H5_ATTR_UNUSED *dst_oloc, void *mesg_dst,
1614 H5O_copy_t H5_ATTR_UNUSED *cpy_info)
1615 {
1616 H5T_t *dt_dst = (H5T_t *)mesg_dst; /* Destination datatype */
1617 herr_t ret_value = SUCCEED; /* Return value */
1618
1619 FUNC_ENTER_STATIC
1620
1621 if(dt_dst->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
1622 HDassert(H5T_committed(dt_dst));
1623 if(H5O_loc_reset(&(dt_dst->oloc)) < 0)
1624 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to reset location")
1625 dt_dst->oloc.file = dt_dst->sh_loc.file;
1626 dt_dst->oloc.addr = dt_dst->sh_loc.u.loc.oh_addr;
1627 } /* end if */
1628 else
1629 HDassert(!H5T_committed(dt_dst));
1630
1631 done:
1632 FUNC_LEAVE_NOAPI(ret_value)
1633 } /* end H5O__dtype_shared_post_copy_upd */
1634
1635
1636 /*--------------------------------------------------------------------------
1637 NAME
1638 H5O__dtype_debug
1639 PURPOSE
1640 Prints debugging information for a message
1641 USAGE
1642 void *H5O__dtype_debug(f, mesg, stream, indent, fwidth)
1643 H5F_t *f; IN: pointer to the HDF5 file struct
1644 const void *mesg; IN: Pointer to the source simple datatype
1645 struct
1646 FILE *stream; IN: Pointer to the stream for output data
1647 int indent; IN: Amount to indent information by
1648 int fwidth; IN: Field width (?)
1649 RETURNS
1650 Non-negative on success/Negative on failure
1651 DESCRIPTION
1652 This function prints debugging output to the stream passed as a
1653 parameter.
1654 --------------------------------------------------------------------------*/
1655 static herr_t
H5O__dtype_debug(H5F_t * f,const void * mesg,FILE * stream,int indent,int fwidth)1656 H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent,
1657 int fwidth)
1658 {
1659 const H5T_t *dt = (const H5T_t*)mesg;
1660 const char *s;
1661 char buf[256];
1662 unsigned i;
1663 size_t k;
1664
1665 FUNC_ENTER_STATIC_NOERR
1666
1667 /* check args */
1668 HDassert(f);
1669 HDassert(dt);
1670 HDassert(stream);
1671 HDassert(indent >= 0);
1672 HDassert(fwidth >= 0);
1673
1674 switch (dt->shared->type) {
1675 case H5T_INTEGER:
1676 s = "integer";
1677 break;
1678
1679 case H5T_FLOAT:
1680 s = "floating-point";
1681 break;
1682
1683 case H5T_TIME:
1684 s = "date and time";
1685 break;
1686
1687 case H5T_STRING:
1688 s = "text string";
1689 break;
1690
1691 case H5T_BITFIELD:
1692 s = "bit field";
1693 break;
1694
1695 case H5T_OPAQUE:
1696 s = "opaque";
1697 break;
1698
1699 case H5T_COMPOUND:
1700 s = "compound";
1701 break;
1702
1703 case H5T_REFERENCE:
1704 s = "reference";
1705 break;
1706
1707 case H5T_ENUM:
1708 s = "enum";
1709 break;
1710
1711 case H5T_ARRAY:
1712 s = "array";
1713 break;
1714
1715 case H5T_VLEN:
1716 s = "vlen";
1717 break;
1718
1719 case H5T_NO_CLASS:
1720 case H5T_NCLASSES:
1721 default:
1722 HDsprintf(buf, "H5T_CLASS_%d", (int)(dt->shared->type));
1723 s = buf;
1724 break;
1725 } /* end switch */
1726 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1727 "Type class:",
1728 s);
1729
1730 HDfprintf(stream, "%*s%-*s %lu byte%s\n", indent, "", fwidth,
1731 "Size:",
1732 (unsigned long)(dt->shared->size), 1 == dt->shared->size ? "" : "s");
1733
1734 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1735 "Version:", dt->shared->version);
1736
1737 if (H5T_COMPOUND == dt->shared->type) {
1738 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1739 "Number of members:",
1740 dt->shared->u.compnd.nmembs);
1741 for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
1742 HDsprintf(buf, "Member %u:", i);
1743 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1744 buf,
1745 dt->shared->u.compnd.memb[i].name);
1746 HDfprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0, fwidth-3),
1747 "Byte offset:",
1748 (unsigned long)(dt->shared->u.compnd.memb[i].offset));
1749 H5O__dtype_debug(f, dt->shared->u.compnd.memb[i].type, stream,
1750 indent + 3, MAX(0, fwidth - 3));
1751 } /* end for */
1752 } /* end if */
1753 else if(H5T_ENUM == dt->shared->type) {
1754 HDfprintf(stream, "%*s%s\n", indent, "", "Base type:");
1755 H5O__dtype_debug(f, dt->shared->parent, stream, indent+3, MAX(0, fwidth-3));
1756 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1757 "Number of members:",
1758 dt->shared->u.enumer.nmembs);
1759 for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
1760 HDsprintf(buf, "Member %u:", i);
1761 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1762 buf,
1763 dt->shared->u.enumer.name[i]);
1764 HDfprintf(stream, "%*s%-*s 0x", indent, "", fwidth,
1765 "Raw bytes of value:");
1766 for(k = 0; k < dt->shared->parent->shared->size; k++)
1767 HDfprintf(stream, "%02x", dt->shared->u.enumer.value[i*dt->shared->parent->shared->size + k]);
1768 HDfprintf(stream, "\n");
1769 } /* end for */
1770 } /* end else if */
1771 else if(H5T_OPAQUE == dt->shared->type) {
1772 HDfprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth,
1773 "Tag:", dt->shared->u.opaque.tag);
1774 } /* end else if */
1775 else if(H5T_REFERENCE == dt->shared->type) {
1776 HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth,
1777 "Fix dumping reference types!");
1778 } /* end else if */
1779 else if(H5T_STRING == dt->shared->type) {
1780 switch(dt->shared->u.atomic.u.s.cset) {
1781 case H5T_CSET_ASCII:
1782 s = "ASCII";
1783 break;
1784
1785 case H5T_CSET_UTF8:
1786 s = "UTF-8";
1787 break;
1788
1789 case H5T_CSET_RESERVED_2:
1790 case H5T_CSET_RESERVED_3:
1791 case H5T_CSET_RESERVED_4:
1792 case H5T_CSET_RESERVED_5:
1793 case H5T_CSET_RESERVED_6:
1794 case H5T_CSET_RESERVED_7:
1795 case H5T_CSET_RESERVED_8:
1796 case H5T_CSET_RESERVED_9:
1797 case H5T_CSET_RESERVED_10:
1798 case H5T_CSET_RESERVED_11:
1799 case H5T_CSET_RESERVED_12:
1800 case H5T_CSET_RESERVED_13:
1801 case H5T_CSET_RESERVED_14:
1802 case H5T_CSET_RESERVED_15:
1803 HDsprintf(buf, "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.cset));
1804 s = buf;
1805 break;
1806
1807 case H5T_CSET_ERROR:
1808 default:
1809 HDsprintf(buf, "Unknown character set: %d", (int)(dt->shared->u.atomic.u.s.cset));
1810 s = buf;
1811 break;
1812 } /* end switch */
1813 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1814 "Character Set:",
1815 s);
1816
1817 switch(dt->shared->u.atomic.u.s.pad) {
1818 case H5T_STR_NULLTERM:
1819 s = "NULL Terminated";
1820 break;
1821
1822 case H5T_STR_NULLPAD:
1823 s = "NULL Padded";
1824 break;
1825
1826 case H5T_STR_SPACEPAD:
1827 s = "Space Padded";
1828 break;
1829
1830 case H5T_STR_RESERVED_3:
1831 case H5T_STR_RESERVED_4:
1832 case H5T_STR_RESERVED_5:
1833 case H5T_STR_RESERVED_6:
1834 case H5T_STR_RESERVED_7:
1835 case H5T_STR_RESERVED_8:
1836 case H5T_STR_RESERVED_9:
1837 case H5T_STR_RESERVED_10:
1838 case H5T_STR_RESERVED_11:
1839 case H5T_STR_RESERVED_12:
1840 case H5T_STR_RESERVED_13:
1841 case H5T_STR_RESERVED_14:
1842 case H5T_STR_RESERVED_15:
1843 HDsprintf(buf, "H5T_STR_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.pad));
1844 s = buf;
1845 break;
1846
1847 case H5T_STR_ERROR:
1848 default:
1849 HDsprintf(buf, "Unknown string padding: %d", (int)(dt->shared->u.atomic.u.s.pad));
1850 s = buf;
1851 break;
1852 } /* end switch */
1853 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1854 "String Padding:",
1855 s);
1856 } /* end else if */
1857 else if(H5T_VLEN == dt->shared->type) {
1858 switch(dt->shared->u.vlen.type) {
1859 case H5T_VLEN_SEQUENCE:
1860 s = "sequence";
1861 break;
1862
1863 case H5T_VLEN_STRING:
1864 s = "string";
1865 break;
1866
1867 case H5T_VLEN_BADTYPE:
1868 case H5T_VLEN_MAXTYPE:
1869 default:
1870 HDsprintf(buf, "H5T_VLEN_%d", dt->shared->u.vlen.type);
1871 s = buf;
1872 break;
1873 } /* end switch */
1874 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1875 "Vlen type:", s);
1876
1877 switch(dt->shared->u.vlen.loc) {
1878 case H5T_LOC_MEMORY:
1879 s = "memory";
1880 break;
1881
1882 case H5T_LOC_DISK:
1883 s = "disk";
1884 break;
1885
1886 case H5T_LOC_BADLOC:
1887 case H5T_LOC_MAXLOC:
1888 default:
1889 HDsprintf(buf, "H5T_LOC_%d", (int)dt->shared->u.vlen.loc);
1890 s = buf;
1891 break;
1892 } /* end switch */
1893 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1894 "Location:", s);
1895
1896 /* Extra information for VL-strings */
1897 if(dt->shared->u.vlen.type == H5T_VLEN_STRING) {
1898 switch(dt->shared->u.vlen.cset) {
1899 case H5T_CSET_ASCII:
1900 s = "ASCII";
1901 break;
1902
1903 case H5T_CSET_UTF8:
1904 s = "UTF-8";
1905 break;
1906
1907 case H5T_CSET_RESERVED_2:
1908 case H5T_CSET_RESERVED_3:
1909 case H5T_CSET_RESERVED_4:
1910 case H5T_CSET_RESERVED_5:
1911 case H5T_CSET_RESERVED_6:
1912 case H5T_CSET_RESERVED_7:
1913 case H5T_CSET_RESERVED_8:
1914 case H5T_CSET_RESERVED_9:
1915 case H5T_CSET_RESERVED_10:
1916 case H5T_CSET_RESERVED_11:
1917 case H5T_CSET_RESERVED_12:
1918 case H5T_CSET_RESERVED_13:
1919 case H5T_CSET_RESERVED_14:
1920 case H5T_CSET_RESERVED_15:
1921 HDsprintf(buf, "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.vlen.cset));
1922 s = buf;
1923 break;
1924
1925 case H5T_CSET_ERROR:
1926 default:
1927 HDsprintf(buf, "Unknown character set: %d", (int)(dt->shared->u.vlen.cset));
1928 s = buf;
1929 break;
1930 } /* end switch */
1931 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1932 "Character Set:",
1933 s);
1934
1935 switch(dt->shared->u.vlen.pad) {
1936 case H5T_STR_NULLTERM:
1937 s = "NULL Terminated";
1938 break;
1939
1940 case H5T_STR_NULLPAD:
1941 s = "NULL Padded";
1942 break;
1943
1944 case H5T_STR_SPACEPAD:
1945 s = "Space Padded";
1946 break;
1947
1948 case H5T_STR_RESERVED_3:
1949 case H5T_STR_RESERVED_4:
1950 case H5T_STR_RESERVED_5:
1951 case H5T_STR_RESERVED_6:
1952 case H5T_STR_RESERVED_7:
1953 case H5T_STR_RESERVED_8:
1954 case H5T_STR_RESERVED_9:
1955 case H5T_STR_RESERVED_10:
1956 case H5T_STR_RESERVED_11:
1957 case H5T_STR_RESERVED_12:
1958 case H5T_STR_RESERVED_13:
1959 case H5T_STR_RESERVED_14:
1960 case H5T_STR_RESERVED_15:
1961 HDsprintf(buf, "H5T_STR_RESERVED_%d", (int)(dt->shared->u.vlen.pad));
1962 s = buf;
1963 break;
1964
1965 case H5T_STR_ERROR:
1966 default:
1967 HDsprintf(buf, "Unknown string padding: %d", (int)(dt->shared->u.vlen.pad));
1968 s = buf;
1969 break;
1970 } /* end switch */
1971 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
1972 "String Padding:",
1973 s);
1974 } /* end if */
1975 } /* end else if */
1976 else if(H5T_ARRAY == dt->shared->type) {
1977 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
1978 "Rank:",
1979 dt->shared->u.array.ndims);
1980 HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Size:");
1981 for(i = 0; i < dt->shared->u.array.ndims; i++)
1982 HDfprintf(stream, "%s%u", (i ? ", " : ""), (unsigned)dt->shared->u.array.dim[i]);
1983 HDfprintf(stream, "}\n");
1984 HDfprintf(stream, "%*s%s\n", indent, "", "Base type:");
1985 H5O__dtype_debug(f, dt->shared->parent, stream, indent + 3, MAX(0, fwidth - 3));
1986 } /* end else if */
1987 else {
1988 switch (dt->shared->u.atomic.order) {
1989 case H5T_ORDER_LE:
1990 s = "little endian";
1991 break;
1992
1993 case H5T_ORDER_BE:
1994 s = "big endian";
1995 break;
1996
1997 case H5T_ORDER_VAX:
1998 s = "VAX";
1999 break;
2000
2001 case H5T_ORDER_NONE:
2002 s = "none";
2003 break;
2004
2005 case H5T_ORDER_MIXED:
2006 s = "mixed";
2007 break;
2008
2009 case H5T_ORDER_ERROR:
2010 default:
2011 HDsprintf(buf, "H5T_ORDER_%d", dt->shared->u.atomic.order);
2012 s = buf;
2013 break;
2014 } /* end switch */
2015 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2016 "Byte order:",
2017 s);
2018
2019 HDfprintf(stream, "%*s%-*s %lu bit%s\n", indent, "", fwidth,
2020 "Precision:",
2021 (unsigned long)(dt->shared->u.atomic.prec),
2022 1==dt->shared->u.atomic.prec?"":"s");
2023
2024 HDfprintf(stream, "%*s%-*s %lu bit%s\n", indent, "", fwidth,
2025 "Offset:",
2026 (unsigned long)(dt->shared->u.atomic.offset),
2027 1==dt->shared->u.atomic.offset?"":"s");
2028
2029 switch (dt->shared->u.atomic.lsb_pad) {
2030 case H5T_PAD_ZERO:
2031 s = "zero";
2032 break;
2033
2034 case H5T_PAD_ONE:
2035 s = "one";
2036 break;
2037
2038 case H5T_PAD_BACKGROUND:
2039 s = "background";
2040 break;
2041
2042 case H5T_PAD_ERROR:
2043 case H5T_NPAD:
2044 default:
2045 s = "pad?";
2046 break;
2047 } /* end switch */
2048 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2049 "Low pad type:", s);
2050
2051 switch (dt->shared->u.atomic.msb_pad) {
2052 case H5T_PAD_ZERO:
2053 s = "zero";
2054 break;
2055
2056 case H5T_PAD_ONE:
2057 s = "one";
2058 break;
2059
2060 case H5T_PAD_BACKGROUND:
2061 s = "background";
2062 break;
2063
2064 case H5T_PAD_ERROR:
2065 case H5T_NPAD:
2066 default:
2067 s = "pad?";
2068 break;
2069 } /* end switch */
2070 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2071 "High pad type:", s);
2072
2073 if (H5T_FLOAT == dt->shared->type) {
2074 switch (dt->shared->u.atomic.u.f.pad) {
2075 case H5T_PAD_ZERO:
2076 s = "zero";
2077 break;
2078
2079 case H5T_PAD_ONE:
2080 s = "one";
2081 break;
2082
2083 case H5T_PAD_BACKGROUND:
2084 s = "background";
2085 break;
2086
2087 case H5T_PAD_ERROR:
2088 case H5T_NPAD:
2089 default:
2090 if (dt->shared->u.atomic.u.f.pad < 0)
2091 HDsprintf(buf, "H5T_PAD_%d", -(dt->shared->u.atomic.u.f.pad));
2092 else
2093 HDsprintf(buf, "bit-%d", dt->shared->u.atomic.u.f.pad);
2094 s = buf;
2095 break;
2096 } /* end switch */
2097 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2098 "Internal pad type:", s);
2099
2100 switch (dt->shared->u.atomic.u.f.norm) {
2101 case H5T_NORM_IMPLIED:
2102 s = "implied";
2103 break;
2104
2105 case H5T_NORM_MSBSET:
2106 s = "msb set";
2107 break;
2108
2109 case H5T_NORM_NONE:
2110 s = "none";
2111 break;
2112
2113 case H5T_NORM_ERROR:
2114 default:
2115 HDsprintf(buf, "H5T_NORM_%d", (int) (dt->shared->u.atomic.u.f.norm));
2116 s = buf;
2117 } /* end switch */
2118 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2119 "Normalization:", s);
2120
2121 HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2122 "Sign bit location:",
2123 (unsigned long) (dt->shared->u.atomic.u.f.sign));
2124
2125 HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2126 "Exponent location:",
2127 (unsigned long) (dt->shared->u.atomic.u.f.epos));
2128
2129 HDfprintf(stream, "%*s%-*s 0x%08lx\n", indent, "", fwidth,
2130 "Exponent bias:",
2131 (unsigned long) (dt->shared->u.atomic.u.f.ebias));
2132
2133 HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2134 "Exponent size:",
2135 (unsigned long) (dt->shared->u.atomic.u.f.esize));
2136
2137 HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2138 "Mantissa location:",
2139 (unsigned long) (dt->shared->u.atomic.u.f.mpos));
2140
2141 HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
2142 "Mantissa size:",
2143 (unsigned long) (dt->shared->u.atomic.u.f.msize));
2144
2145 } /* end if */
2146 else if (H5T_INTEGER == dt->shared->type) {
2147 switch (dt->shared->u.atomic.u.i.sign) {
2148 case H5T_SGN_NONE:
2149 s = "none";
2150 break;
2151
2152 case H5T_SGN_2:
2153 s = "2's comp";
2154 break;
2155
2156 case H5T_SGN_ERROR:
2157 case H5T_NSGN:
2158 default:
2159 HDsprintf(buf, "H5T_SGN_%d", (int) (dt->shared->u.atomic.u.i.sign));
2160 s = buf;
2161 break;
2162 } /* end switch */
2163 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
2164 "Sign scheme:", s);
2165 } /* end else if */
2166 } /* end else */
2167
2168 FUNC_LEAVE_NOAPI(SUCCEED)
2169 } /* end H5O__dtype_debug() */
2170
2171