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