1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*
15 * Module Info: This module contains the functionality for compound datatypes
16 * in the H5T interface.
17 */
18
19 /****************/
20 /* Module Setup */
21 /****************/
22
23 #include "H5Tmodule.h" /* This source code file is part of the H5T module */
24
25
26 /***********/
27 /* Headers */
28 /***********/
29 #include "H5private.h" /*generic functions */
30 #include "H5CXprivate.h" /*API Contexts */
31 #include "H5Eprivate.h" /*error handling */
32 #include "H5Iprivate.h" /*ID functions */
33 #include "H5MMprivate.h" /*memory management */
34 #include "H5Tpkg.h" /*data-type functions */
35
36 /****************/
37 /* Local Macros */
38 /****************/
39
40
41 /******************/
42 /* Local Typedefs */
43 /******************/
44
45
46 /********************/
47 /* Package Typedefs */
48 /********************/
49
50
51 /********************/
52 /* Local Prototypes */
53 /********************/
54 static herr_t H5T_pack(const H5T_t *dt);
55 static htri_t H5T_is_packed(const H5T_t *dt);
56
57
58 /*********************/
59 /* Public Variables */
60 /*********************/
61
62
63 /*********************/
64 /* Package Variables */
65 /*********************/
66
67
68 /*****************************/
69 /* Library Private Variables */
70 /*****************************/
71
72
73 /*******************/
74 /* Local Variables */
75 /*******************/
76
77
78
79 /*-------------------------------------------------------------------------
80 * Function: H5Tget_member_offset
81 *
82 * Purpose: Returns the byte offset of the beginning of a member with
83 * respect to the beginning of the compound datatype datum.
84 *
85 * Return: Success: Byte offset.
86 *
87 * Failure: Zero. Zero is a valid offset, but this
88 * function will fail only if a call to
89 * H5Tget_member_dims() fails with the same
90 * arguments.
91 *
92 * Programmer: Robb Matzke
93 * Wednesday, January 7, 1998
94 *
95 * Modifications:
96 *
97 *-------------------------------------------------------------------------
98 */
99 size_t
H5Tget_member_offset(hid_t type_id,unsigned membno)100 H5Tget_member_offset(hid_t type_id, unsigned membno)
101 {
102 H5T_t *dt; /* Datatype to query */
103 size_t ret_value; /* Return value */
104
105 FUNC_ENTER_API(0)
106 H5TRACE2("z", "iIu", type_id, membno);
107
108 /* Check args */
109 if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
110 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a compound datatype")
111 if(membno >= dt->shared->u.compnd.nmembs)
112 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid member number")
113
114 /* Value */
115 ret_value = H5T_GET_MEMBER_OFFSET(dt->shared, membno);
116
117 done:
118 FUNC_LEAVE_API(ret_value)
119 } /* end H5Tget_member_offset() */
120
121
122 /*-------------------------------------------------------------------------
123 * Function: H5T_get_member_offset
124 *
125 * Purpose: Private function for H5Tget_member_offset. Returns the byte
126 * offset of the beginning of a member with respect to the
127 * beginning of the compound datatype datum.
128 *
129 * Return: Success: Byte offset.
130 *
131 * Failure: Zero. Zero is a valid offset, but this
132 * function will fail only if a call to
133 * H5Tget_member_dims() fails with the same
134 * arguments.
135 *
136 * Programmer: Raymond Lu
137 * October 8, 2002
138 *
139 *-------------------------------------------------------------------------
140 */
141 size_t
H5T_get_member_offset(const H5T_t * dt,unsigned membno)142 H5T_get_member_offset(const H5T_t *dt, unsigned membno)
143 {
144 FUNC_ENTER_NOAPI_NOINIT_NOERR
145
146 HDassert(dt);
147 HDassert(membno < dt->shared->u.compnd.nmembs);
148
149 FUNC_LEAVE_NOAPI(dt->shared->u.compnd.memb[membno].offset)
150 } /* end H5T_get_member_offset() */
151
152
153 /*-------------------------------------------------------------------------
154 * Function: H5Tget_member_class
155 *
156 * Purpose: Returns the datatype class of a member of a compound datatype.
157 *
158 * Return: Success: Non-negative
159 *
160 * Failure: H5T_NO_CLASS
161 *
162 * Programmer: Quincey Koziol
163 * Thursday, November 9, 2000
164 *
165 * Modifications:
166 *
167 *-------------------------------------------------------------------------
168 */
169 H5T_class_t
H5Tget_member_class(hid_t type_id,unsigned membno)170 H5Tget_member_class(hid_t type_id, unsigned membno)
171 {
172 H5T_t *dt; /* Datatype to query */
173 H5T_class_t ret_value; /* Return value */
174
175 FUNC_ENTER_API(H5T_NO_CLASS)
176 H5TRACE2("Tt", "iIu", type_id, membno);
177
178 /* Check args */
179 if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
180 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a compound datatype")
181 if(membno >= dt->shared->u.compnd.nmembs)
182 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5T_NO_CLASS, "invalid member number")
183
184 /* Get the type's class. We have to use this function to get type class
185 * because of the concern of variable-length string.
186 */
187 ret_value = H5T_GET_CLASS(dt->shared->u.compnd.memb[membno].type->shared, FALSE);
188
189 done:
190 FUNC_LEAVE_API(ret_value)
191 } /* end H5Tget_member_class() */
192
193
194 /*-------------------------------------------------------------------------
195 * Function: H5Tget_member_type
196 *
197 * Purpose: Returns the datatype of the specified member. The caller
198 * should invoke H5Tclose() to release resources associated with
199 * the type.
200 *
201 * Return: Success: An OID of a copy of the member datatype;
202 * modifying the returned datatype does not
203 * modify the member type.
204 *
205 * Failure: Negative
206 *
207 * Programmer: Robb Matzke
208 * Wednesday, January 7, 1998
209 *
210 *-------------------------------------------------------------------------
211 */
212 hid_t
H5Tget_member_type(hid_t type_id,unsigned membno)213 H5Tget_member_type(hid_t type_id, unsigned membno)
214 {
215 H5T_t *dt; /* Datatype to query */
216 H5T_t *memb_dt = NULL; /* Member datatype */
217 hid_t ret_value; /* Return value */
218
219 FUNC_ENTER_API(H5I_INVALID_HID)
220 H5TRACE2("i", "iIu", type_id, membno);
221
222 /* Check args */
223 if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
224 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a compound datatype")
225 if(membno >= dt->shared->u.compnd.nmembs)
226 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid member number")
227
228 /* Retrieve the datatype for the member */
229 if(NULL == (memb_dt = H5T_get_member_type(dt, membno, H5T_COPY_REOPEN)))
230 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5I_INVALID_HID, "unable to retrieve member type")
231
232 /* Get an ID for the datatype */
233 if((ret_value = H5I_register(H5I_DATATYPE, memb_dt, TRUE)) < 0)
234 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable register datatype atom")
235
236 done:
237 if(ret_value < 0)
238 if(memb_dt && H5T_close(memb_dt) < 0)
239 HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, H5I_INVALID_HID, "can't close datatype")
240
241 FUNC_LEAVE_API(ret_value)
242 } /* end H5Tget_member_type() */
243
244
245 /*-------------------------------------------------------------------------
246 * Function: H5T_get_member_type
247 *
248 * Purpose: Private function for H5Tget_member_type. Returns the data
249 * type of the specified member.
250 *
251 * Return: Success: A copy of the member datatype;
252 * modifying the returned datatype does not
253 * modify the member type.
254 *
255 * Failure: NULL
256 *
257 * Programmer: Raymond Lu
258 * October 8, 2002
259 *
260 *-------------------------------------------------------------------------
261 */
262 H5T_t *
H5T_get_member_type(const H5T_t * dt,unsigned membno,H5T_copy_t method)263 H5T_get_member_type(const H5T_t *dt, unsigned membno, H5T_copy_t method)
264 {
265 H5T_t *ret_value = NULL; /* Return value */
266
267 FUNC_ENTER_NOAPI(NULL)
268
269 HDassert(dt);
270 HDassert(membno < dt->shared->u.compnd.nmembs);
271
272 /* Copy datatype into an atom */
273 if(NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, method)))
274 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member datatype")
275
276 done:
277 FUNC_LEAVE_NOAPI(ret_value)
278 } /* end H5T_get_member_type() */
279
280
281 /*-------------------------------------------------------------------------
282 * Function: H5T__get_member_size
283 *
284 * Purpose: Returns the size of the specified member.
285 *
286 * Return: Success: The size in bytes of the member's datatype.
287 * Failure: 0
288 *
289 * Programmer: Quincey Koziol
290 * October 4, 2004
291 *
292 *-------------------------------------------------------------------------
293 */
294 size_t
H5T__get_member_size(const H5T_t * dt,unsigned membno)295 H5T__get_member_size(const H5T_t *dt, unsigned membno)
296 {
297 FUNC_ENTER_PACKAGE_NOERR
298
299 HDassert(dt);
300 HDassert(membno < dt->shared->u.compnd.nmembs);
301
302 FUNC_LEAVE_NOAPI(dt->shared->u.compnd.memb[membno].type->shared->size)
303 } /* end H5T__get_member_size() */
304
305
306 /*-------------------------------------------------------------------------
307 * Function: H5Tinsert
308 *
309 * Purpose: Adds another member to the compound datatype PARENT_ID. The
310 * new member has a NAME which must be unique within the
311 * compound datatype. The OFFSET argument defines the start of
312 * the member in an instance of the compound datatype, and
313 * MEMBER_ID is the type of the new member.
314 *
315 * Return: Success: Non-negative, the PARENT_ID compound data
316 * type is modified to include a copy of the
317 * member type MEMBER_ID.
318 *
319 * Failure: Negative
320 *
321 * Errors:
322 *
323 * Programmer: Robb Matzke
324 * Monday, December 8, 1997
325 *
326 * Modifications:
327 *
328 *-------------------------------------------------------------------------
329 */
330 herr_t
H5Tinsert(hid_t parent_id,const char * name,size_t offset,hid_t member_id)331 H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id)
332 {
333 H5T_t *parent; /* The compound parent datatype */
334 H5T_t *member; /* The member datatype */
335 herr_t ret_value = SUCCEED; /* Return value */
336
337 FUNC_ENTER_API(FAIL)
338 H5TRACE4("e", "i*szi", parent_id, name, offset, member_id);
339
340 /* Check args */
341 if(parent_id == member_id)
342 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't insert compound datatype within itself")
343 if(NULL == (parent = (H5T_t *)H5I_object_verify(parent_id, H5I_DATATYPE)) || H5T_COMPOUND != parent->shared->type)
344 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
345 if(H5T_STATE_TRANSIENT != parent->shared->state)
346 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only")
347 if(!name || !*name)
348 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no member name")
349 if(NULL == (member = (H5T_t *)H5I_object_verify(member_id, H5I_DATATYPE)))
350 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
351
352 /* Insert */
353 if(H5T__insert(parent, name, offset, member) < 0)
354 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "unable to insert member")
355
356 done:
357 FUNC_LEAVE_API(ret_value)
358 } /* end H5Tinsert() */
359
360
361 /*-------------------------------------------------------------------------
362 * Function: H5Tpack
363 *
364 * Purpose: Recursively removes padding from within a compound datatype
365 * to make it more efficient (space-wise) to store that data.
366 *
367 * Return: Non-negative on success/Negative on failure
368 *
369 * Programmer: Robb Matzke
370 * Wednesday, January 7, 1998
371 *
372 * Modifications:
373 *
374 *-------------------------------------------------------------------------
375 */
376 herr_t
H5Tpack(hid_t type_id)377 H5Tpack(hid_t type_id)
378 {
379 H5T_t *dt; /* Datatype to modify */
380 herr_t ret_value = SUCCEED; /* Return value */
381
382 FUNC_ENTER_API(FAIL)
383 H5TRACE1("e", "i", type_id);
384
385 /* Check args */
386 if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_detect_class(dt, H5T_COMPOUND, TRUE) <= 0)
387 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
388
389 /* Pack */
390 if(H5T_pack(dt) < 0)
391 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound datatype")
392
393 done:
394 FUNC_LEAVE_API(ret_value)
395 } /* end H5Tpack() */
396
397
398 /*-------------------------------------------------------------------------
399 * Function: H5T__insert
400 *
401 * Purpose: Adds a new MEMBER to the compound datatype PARENT. The new
402 * member will have a NAME that is unique within PARENT and an
403 * instance of PARENT will have the member begin at byte offset
404 * OFFSET from the beginning.
405 *
406 * Return: Non-negative on success/Negative on failure
407 *
408 * Programmer: Robb Matzke
409 * Monday, December 8, 1997
410 *
411 *-------------------------------------------------------------------------
412 */
413 herr_t
H5T__insert(H5T_t * parent,const char * name,size_t offset,const H5T_t * member)414 H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
415 {
416 unsigned idx; /* Index of member to insert */
417 size_t total_size;
418 unsigned i; /* Local index variable */
419 herr_t ret_value = SUCCEED; /* Return value */
420
421 FUNC_ENTER_PACKAGE
422
423 /* check args */
424 HDassert(parent && H5T_COMPOUND == parent->shared->type);
425 HDassert(H5T_STATE_TRANSIENT == parent->shared->state);
426 HDassert(member);
427 HDassert(name && *name);
428
429 /* Does NAME already exist in PARENT? */
430 for(i = 0; i < parent->shared->u.compnd.nmembs; i++)
431 if(!HDstrcmp(parent->shared->u.compnd.memb[i].name, name))
432 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique")
433
434 /* Does the new member overlap any existing member ? */
435 total_size = member->shared->size;
436 for(i = 0; i < parent->shared->u.compnd.nmembs; i++)
437 if((offset <= parent->shared->u.compnd.memb[i].offset &&
438 (offset + total_size) > parent->shared->u.compnd.memb[i].offset) ||
439 (parent->shared->u.compnd.memb[i].offset <= offset &&
440 (parent->shared->u.compnd.memb[i].offset +
441 parent->shared->u.compnd.memb[i].size) > offset))
442 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
443
444 /* Does the new member overlap the end of the compound type? */
445 if((offset + total_size) > parent->shared->size)
446 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type")
447
448 /* Increase member array if necessary */
449 if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) {
450 unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2);
451 H5T_cmemb_t *x = (H5T_cmemb_t *)H5MM_realloc(parent->shared->u.compnd.memb, na * sizeof(H5T_cmemb_t));
452
453 if(!x)
454 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed")
455 parent->shared->u.compnd.nalloc = na;
456 parent->shared->u.compnd.memb = x;
457 } /* end if */
458
459 /* Add member to end of member array */
460 idx = parent->shared->u.compnd.nmembs;
461 parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name);
462 parent->shared->u.compnd.memb[idx].offset = offset;
463 parent->shared->u.compnd.memb[idx].size = total_size;
464 parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL);
465
466 parent->shared->u.compnd.sorted = H5T_SORT_NONE;
467 parent->shared->u.compnd.nmembs++;
468 parent->shared->u.compnd.memb_size+=total_size;
469
470 /* It should not be possible to get this far if the type is already packed
471 * - the new member would overlap something */
472 HDassert(!(parent->shared->u.compnd.packed));
473
474 /* Determine if the compound datatype becomes packed */
475 H5T__update_packed(parent);
476
477 /* Set the "force conversion" flag if the field's datatype indicates */
478 if(member->shared->force_conv == TRUE)
479 parent->shared->force_conv = TRUE;
480
481 /* Check for member having a later version than the parent */
482 if(parent->shared->version < member->shared->version)
483 /* Upgrade parent datatype (and all other members also) */
484 /* (can't use a partial datatype and later versions of the format are
485 * more efficient, so might as well upgrade all members also... -QAK)
486 */
487 if(H5T__upgrade_version(parent, member->shared->version) < 0)
488 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade member encoding version")
489
490 done:
491 FUNC_LEAVE_NOAPI(ret_value)
492 } /* end H5T__insert() */
493
494
495 /*-------------------------------------------------------------------------
496 * Function: H5T_pack
497 *
498 * Purpose: Recursively packs a compound datatype by removing padding
499 * bytes. This is done in place (that is, destructively).
500 *
501 * Return: Non-negative on success/Negative on failure
502 *
503 * Programmer: Robb Matzke
504 * Wednesday, January 7, 1998
505 *
506 *-------------------------------------------------------------------------
507 */
508 static herr_t
H5T_pack(const H5T_t * dt)509 H5T_pack(const H5T_t *dt)
510 {
511 herr_t ret_value = SUCCEED; /* Return value */
512
513 FUNC_ENTER_NOAPI_NOINIT
514
515 HDassert(dt);
516
517 if(H5T_detect_class(dt, H5T_COMPOUND, FALSE) > 0) {
518 /* If datatype has been packed, skip packing it and indicate success */
519 if(TRUE == H5T_is_packed(dt))
520 HGOTO_DONE(SUCCEED)
521
522 /* Check for packing unmodifiable datatype */
523 if(H5T_STATE_TRANSIENT != dt->shared->state)
524 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is read-only")
525
526 if(dt->shared->parent) {
527 if (H5T_pack(dt->shared->parent) < 0)
528 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack parent of datatype")
529
530 /* Adjust size of datatype appropriately */
531 if(dt->shared->type == H5T_ARRAY)
532 dt->shared->size = dt->shared->parent->shared->size * dt->shared->u.array.nelem;
533 else if(dt->shared->type != H5T_VLEN)
534 dt->shared->size = dt->shared->parent->shared->size;
535 } /* end if */
536 else if(dt->shared->type == H5T_COMPOUND) {
537 size_t offset; /* Offset of member */
538 unsigned i; /* Local index variable */
539
540 /* Recursively pack the members */
541 for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
542 if(H5T_pack(dt->shared->u.compnd.memb[i].type) < 0)
543 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound datatype")
544
545 /* Update the member size */
546 dt->shared->u.compnd.memb[i].size = (dt->shared->u.compnd.memb[i].type)->shared->size;
547 } /* end for */
548
549 /* Remove padding between members */
550 if(H5T__sort_value(dt, NULL) < 0)
551 HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOMPARE, FAIL, "value sort failed")
552 for(i = 0, offset = 0; i < dt->shared->u.compnd.nmembs; i++) {
553 dt->shared->u.compnd.memb[i].offset = offset;
554 offset += dt->shared->u.compnd.memb[i].size;
555 }
556
557 /* Change total size */
558 dt->shared->size = MAX(1, offset);
559
560 /* Mark the type as packed now */
561 dt->shared->u.compnd.packed = TRUE;
562 } /* end if */
563 } /* end if */
564
565 done:
566 FUNC_LEAVE_NOAPI(ret_value)
567 } /* end H5T_pack() */
568
569
570 /*-------------------------------------------------------------------------
571 * Function: H5T_is_packed
572 *
573 * Purpose: Checks whether a datatype which is compound (or has compound
574 * components) is packed.
575 *
576 * Return: Non-negative on success/Negative on failure
577 *
578 * Programmer: Quincey Koziol
579 * Thursday, September 11, 2003
580 *
581 * Modifications:
582 *
583 *-------------------------------------------------------------------------
584 */
585 static htri_t
H5T_is_packed(const H5T_t * dt)586 H5T_is_packed(const H5T_t *dt)
587 {
588 htri_t ret_value = TRUE; /* Return value */
589
590 FUNC_ENTER_NOAPI_NOINIT_NOERR
591
592 HDassert(dt);
593
594 /* Go up the chain as far as possible */
595 while(dt->shared->parent)
596 dt = dt->shared->parent;
597
598 /* If this is a compound datatype, check if it is packed */
599 if(dt->shared->type == H5T_COMPOUND) {
600 ret_value = (htri_t)(dt->shared->u.compnd.packed);
601 } /* end if */
602
603 FUNC_LEAVE_NOAPI(ret_value)
604 } /* end H5T_is_packed() */
605
606
607 /*-------------------------------------------------------------------------
608 * Function: H5T__update_packed
609 *
610 * Purpose: Checks whether a datatype which is compound became packed
611 * after recent changes. This function does not assume that
612 * the status of the "packed" field is correct, and sets
613 * this field to the correct value.
614 *
615 * Return: void
616 *
617 * Programmer: Neil Fortner
618 * Monday, October 19, 2009
619 *
620 * Modifications:
621 *
622 *-------------------------------------------------------------------------
623 */
624 void
H5T__update_packed(const H5T_t * dt)625 H5T__update_packed(const H5T_t *dt)
626 {
627 unsigned i; /* Index */
628
629 FUNC_ENTER_PACKAGE_NOERR
630
631 HDassert(dt);
632 HDassert(dt->shared->type == H5T_COMPOUND);
633
634 /* First check if all space is used in the "top level" type */
635 if(dt->shared->size == dt->shared->u.compnd.memb_size) {
636 /* Set the packed flag to TRUE */
637 dt->shared->u.compnd.packed = TRUE;
638
639 /* Now check if all members are packed */
640 for(i = 0; i < dt->shared->u.compnd.nmembs; i++)
641 if(!H5T_is_packed(dt->shared->u.compnd.memb[i].type)) {
642 dt->shared->u.compnd.packed = FALSE;
643 break;
644 } /* end if */
645 } /* end if */
646 else
647 dt->shared->u.compnd.packed = FALSE;
648
649 FUNC_LEAVE_NOAPI_VOID
650 } /* end H5T__update_packed() */
651
652