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