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