summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-11-17 20:12:28 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-11-17 20:12:28 (GMT)
commitb2acbc56c61fb388183ca13e8f54bd8ab3dc2899 (patch)
treebfa0dc5d9f61b29dc8d9a0d7d3ee6b19f12710d0 /src/H5O.c
parentd6d549e5bfa37e599255766f3add2accc367548d (diff)
downloadhdf5-b2acbc56c61fb388183ca13e8f54bd8ab3dc2899.zip
hdf5-b2acbc56c61fb388183ca13e8f54bd8ab3dc2899.tar.gz
hdf5-b2acbc56c61fb388183ca13e8f54bd8ab3dc2899.tar.bz2
[svn-r12938] Description:
Add src/H5Oalloc.c file forgotten in previous object header checkin Break out more object header routines into separate file (debugging routines this time). Fix "//" style comment in recent ISOHM source changes. Fix 'size_t' vs. 'unsigned' problem (visible in 64-bit testing) in recent ISOHM test changes. Tested on: FreeBSD/32 4.11 (sleipnir) Linux/32 2.4 (heping) Linux/64 2.4 (mir)
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c1774
1 files changed, 2 insertions, 1772 deletions
diff --git a/src/H5O.c b/src/H5O.c
index dba50a6..365ddfb 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -51,8 +51,6 @@
/* Local Macros */
/****************/
-#define H5O_MIN_SIZE 32 /*min obj header data size */
-
/* Load native information for a message, if it's not already present */
/* (Only works for messages with decode callback) */
#define LOAD_NATIVE(F, DXPL, MSG, ERR) \
@@ -71,7 +69,6 @@
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message") \
} /* end if */
-/* Private typedefs */
/******************/
/* Local Typedefs */
@@ -138,28 +135,7 @@ static int H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
unsigned * oh_flags_ptr);
static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_msg_class_t *type,
int sequence, H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
-static herr_t H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg,
- uint8_t *new_gap_loc, size_t new_gap_size);
-static herr_t H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx,
- uint8_t *new_gap_loc, size_t new_gap_size);
-static unsigned H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- const H5O_msg_class_t *type, size_t size, hbool_t * oh_dirtied_ptr);
-static herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc);
-static herr_t H5O_alloc_null(H5O_t *oh, unsigned null_idx,
- const H5O_msg_class_t *new_type, void *new_native, size_t new_size);
-static herr_t H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- H5O_mesg_t *mesg, hbool_t delete_mesg, hbool_t adj_link);
-static htri_t H5O_move_msgs_forward(H5O_t *oh);
-static htri_t H5O_merge_null(H5O_t *oh);
-static htri_t H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
-static herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
-static htri_t H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh,
- unsigned chunkno, size_t size, unsigned * msg_idx);
-static unsigned H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- size_t size);
static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
-static herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg,
- hbool_t adj_link);
static unsigned H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags,
const H5O_msg_class_t *orig_type, const void *orig_mesg, H5O_shared_t *sh_mesg,
const H5O_msg_class_t **new_type, const void **new_mesg, hid_t dxpl_id,
@@ -239,11 +215,6 @@ H5FL_BLK_DEFINE(chunk_image);
/* Declare external the free list for time_t's */
H5FL_EXTERN(time_t);
-/* Declare extern the free list for H5O_cont_t's */
-H5FL_EXTERN(H5O_cont_t);
-
-/* Declare a free list to manage the H5O_addr_map_t struct */
-H5FL_EXTERN(H5O_addr_map_t);
/*-------------------------------------------------------------------------
@@ -2568,1402 +2539,6 @@ done:
/*-------------------------------------------------------------------------
- *
- * Function: H5O_alloc_msgs
- *
- * Purpose: Allocate more messages for a header
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Nov 21 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_alloc_msgs(H5O_t *oh, size_t min_alloc)
-{
- size_t old_alloc; /* Old number of messages allocated */
- size_t na; /* New number of messages allocated */
- H5O_mesg_t *new_mesg; /* Pointer to new message array */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_msgs)
-
- /* check args */
- HDassert(oh);
-
- /* Initialize number of messages information */
- old_alloc = oh->alloc_nmesgs;
- na = oh->alloc_nmesgs + MAX(oh->alloc_nmesgs, min_alloc);
-
- /* Attempt to allocate more memory */
- if(NULL == (new_mesg = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, na)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Update ohdr information */
- oh->alloc_nmesgs = na;
- oh->mesg = new_mesg;
-
- /* Set new object header info to zeros */
- HDmemset(&oh->mesg[old_alloc], 0, (oh->alloc_nmesgs - old_alloc) * sizeof(H5O_mesg_t));
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_alloc_msgs() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_alloc_null
- *
- * Purpose: Allocate room for a new message from a null message
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Oct 22 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type,
- void *new_native, size_t new_size)
-{
- H5O_mesg_t *alloc_msg; /* Pointer to null message to allocate out of */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_null)
-
- /* check args */
- HDassert(oh);
- HDassert(new_type);
- HDassert(new_size);
-
- /* Point to null message to allocate out of */
- alloc_msg = &oh->mesg[null_idx];
-
- /* Check if there's a need to split the null message */
- if(alloc_msg->raw_size > new_size) {
- /* Check for producing a gap in the chunk */
- if((alloc_msg->raw_size - new_size) < (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) {
- size_t gap_size = alloc_msg->raw_size - new_size; /* Size of gap produced */
-
- /* Adjust the size of the null message being eliminated */
- alloc_msg->raw_size = new_size;
-
- /* Add the gap to the chunk */
- if(H5O_add_gap(oh, alloc_msg->chunkno, null_idx, alloc_msg->raw + alloc_msg->raw_size, gap_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't insert gap in chunk")
- } /* end if */
- else {
- size_t new_mesg_size = new_size + H5O_SIZEOF_MSGHDR_OH(oh); /* Total size of newly allocated message */
- H5O_mesg_t *null_msg; /* Pointer to new null message */
-
- /* Check if we need to extend message table to hold the new null message */
- if(oh->nmesgs >= oh->alloc_nmesgs) {
- if(H5O_alloc_msgs(oh, (size_t)1) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
-
- /* "Retarget" 'alloc_msg' pointer into newly re-allocated array of messages */
- alloc_msg = &oh->mesg[null_idx];
- } /* end if */
-
- /* Create new null message, with the tail of the previous null message */
- null_msg = &(oh->mesg[oh->nmesgs++]);
- null_msg->type = H5O_MSG_NULL;
- null_msg->dirty = TRUE;
- null_msg->native = NULL;
- null_msg->raw = alloc_msg->raw + new_mesg_size;
- null_msg->raw_size = alloc_msg->raw_size - new_mesg_size;
- null_msg->chunkno = alloc_msg->chunkno;
-
- /* Check for gap in new null message's chunk */
- if(oh->chunk[null_msg->chunkno].gap > 0) {
- unsigned null_chunkno = null_msg->chunkno; /* Chunk w/gap */
-
- /* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, null_msg,
- ((oh->chunk[null_chunkno].image + oh->chunk[null_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[null_chunkno].gap)),
- oh->chunk[null_chunkno].gap) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, UFAIL, "can't eliminate gap in chunk")
-
- /* Set the gap size to zero for the chunk */
- oh->chunk[null_chunkno].gap = 0;
- } /* end if */
-
- /* Set the size of the new "real" message */
- alloc_msg->raw_size = new_size;
- } /* end else */
- } /* end if */
-
- /* Initialize the new message */
- alloc_msg->type = new_type;
- alloc_msg->dirty = TRUE;
- alloc_msg->native = new_native;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_alloc_null() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_release_mesg
- *
- * Purpose: Convert a message into a null message
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Oct 22 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg,
- hbool_t delete_mesg, hbool_t adj_link)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_release_mesg)
-
- /* check args */
- HDassert(f);
- HDassert(oh);
- HDassert(mesg);
-
- /* Check if we should operate on the message */
- if(delete_mesg) {
- /* Free any space referred to in the file from this message */
- if(H5O_delete_mesg(f, dxpl_id, mesg, adj_link) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
-
- /* Free any native information */
- H5O_free_mesg(mesg);
- } /* end if */
-
- /* Change message type to nil and zero it */
- mesg->type = H5O_MSG_NULL;
- HDassert(mesg->raw + mesg->raw_size <= (oh->chunk[mesg->chunkno].image + oh->chunk[mesg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[mesg->chunkno].gap));
- HDmemset(mesg->raw, 0, mesg->raw_size);
-
- /* Clear message flags */
- mesg->flags = 0;
-
- /* Indicate that the message was modified */
- mesg->dirty = TRUE;
-
- /* Check if chunk has a gap currently */
- if(oh->chunk[mesg->chunkno].gap) {
- /* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, mesg,
- ((oh->chunk[mesg->chunkno].image + oh->chunk[mesg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[mesg->chunkno].gap)),
- oh->chunk[mesg->chunkno].gap) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
-
- /* Set the gap size to zero for the chunk */
- oh->chunk[mesg->chunkno].gap = 0;
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_release_mesg() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_move_msgs_forward
- *
- * Purpose: Move messages toward first chunk
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Oct 17 2005
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5O_move_msgs_forward(H5O_t *oh)
-{
- hbool_t packed_msg; /* Flag to indicate that messages were packed */
- hbool_t did_packing = FALSE; /* Whether any messages were packed */
- htri_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_move_msgs_forward)
-
- /* check args */
- HDassert(oh);
-
- /* Loop until no messages packed */
- /* (Double loop is not very efficient, but it would be some extra work to
- * add a list of messages to each chunk -QAK)
- */
- do {
- H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
- unsigned u; /* Local index variable */
-
- /* Reset packed messages flag */
- packed_msg = FALSE;
-
- /* Scan through messages for messages that can be moved earlier in chunks */
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- if(H5O_NULL_ID == curr_msg->type->id) {
- H5O_chunk_t *chunk; /* Pointer to chunk that null message is in */
-
- /* Check if null message is not last in chunk */
- chunk = &(oh->chunk[curr_msg->chunkno]);
- if((curr_msg->raw + curr_msg->raw_size)
- != ((chunk->image + chunk->size) - (H5O_SIZEOF_CHKSUM_OH(oh) + chunk->gap))) {
- H5O_mesg_t *nonnull_msg; /* Pointer to current message to operate on */
- unsigned v; /* Local index variable */
-
- /* Loop over messages again, looking for the message in the chunk after the null message */
- for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++) {
- /* Locate message that is immediately after the null message */
- if((curr_msg->chunkno == nonnull_msg->chunkno) &&
- ((curr_msg->raw + curr_msg->raw_size) == (nonnull_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)))) {
- /* Don't swap messages if the second message is also a null message */
- /* (We'll merge them together later, in another routine) */
- if(H5O_NULL_ID != nonnull_msg->type->id) {
- /* Copy raw data for non-null message to new location */
- HDmemmove(curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh),
- nonnull_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
-
- /* Adjust non-null message's offset in chunk */
- nonnull_msg->raw = curr_msg->raw;
-
- /* Adjust null message's offset in chunk */
- curr_msg->raw = nonnull_msg->raw +
- nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
-
- /* Mark null message dirty */
- /* (since we need to re-encode its message header) */
- /* (also, marking this message dirty means we
- * don't have to mark chunk as dirty)
- */
- curr_msg->dirty = TRUE;
-
- /* Set the flag to indicate that the null message
- * was packed - if its not at the end its chunk,
- * we'll move it again on the next pass.
- */
- packed_msg = TRUE;
- } /* end if */
-
- /* Break out of loop */
- break;
- } /* end if */
- } /* end for */
- /* Should have been message after null message */
- HDassert(v < oh->nmesgs);
- } /* end if */
- } /* end if */
- else {
- H5O_mesg_t *null_msg; /* Pointer to current message to operate on */
- unsigned v; /* Local index variable */
-
- /* Loop over messages again, looking for large enough null message in earlier chunk */
- for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) {
- if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno
- && curr_msg->raw_size <= null_msg->raw_size) {
- unsigned old_chunkno; /* Old message information */
- uint8_t *old_raw;
-
- /* Keep old information about non-null message */
- old_chunkno = curr_msg->chunkno;
- old_raw = curr_msg->raw;
-
- /* Copy raw data for non-null message to new chunk */
- HDmemcpy(null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
-
- /* Mark null message's chunk as dirty, since the raw data image changed */
- oh->chunk[null_msg->chunkno].dirty = TRUE;
-
- /* Point non-null message at null message's space */
- curr_msg->chunkno = null_msg->chunkno;
- curr_msg->raw = null_msg->raw;
-
- /* Change information for null message */
- if(curr_msg->raw_size == null_msg->raw_size) {
- /* Point null message at old non-null space */
- /* (Instead of freeing it and allocating new message) */
- null_msg->chunkno = old_chunkno;
- null_msg->raw = old_raw;
-
- /* Mark null message dirty */
- null_msg->dirty = TRUE;
- } /* end if */
- else {
- unsigned new_null_msg; /* Message index for new null message */
-
- /* Check if null message is large enough to still exist */
- if((null_msg->raw_size - curr_msg->raw_size) < (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) {
- size_t gap_size = null_msg->raw_size - curr_msg->raw_size; /* Size of gap produced */
-
- /* Adjust the size of the null message being eliminated */
- null_msg->raw_size = curr_msg->raw_size;
-
- /* Add the gap to the chunk */
- if(H5O_add_gap(oh, null_msg->chunkno, v, null_msg->raw + null_msg->raw_size, gap_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk")
-
- /* Re-use message # for new null message taking place of non-null message */
- new_null_msg = v;
- } /* end if */
- else {
- /* Adjust null message's size & offset */
- null_msg->raw += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
- null_msg->raw_size -= curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
-
- /* Mark null message dirty */
- null_msg->dirty = TRUE;
-
- /* Create new null message for previous location of non-null message */
- if(oh->nmesgs >= oh->alloc_nmesgs) {
- if(H5O_alloc_msgs(oh, (size_t)1) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
-
- /* "Retarget" 'curr_msg' pointer into newly re-allocated array of messages */
- curr_msg = &oh->mesg[u];
- } /* end if */
-
- /* Get message # for new null message */
- new_null_msg = oh->nmesgs++;
- } /* end else */
-
- /* Initialize new null message to take over non-null message's location */
- oh->mesg[new_null_msg].type = H5O_MSG_NULL;
- oh->mesg[new_null_msg].dirty = TRUE;
- oh->mesg[new_null_msg].native = NULL;
- oh->mesg[new_null_msg].raw = old_raw;
- oh->mesg[new_null_msg].raw_size = curr_msg->raw_size;
- oh->mesg[new_null_msg].chunkno = old_chunkno;
-
- /* Check for gap in new null message's chunk */
- if(oh->chunk[old_chunkno].gap > 0) {
- /* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, &oh->mesg[new_null_msg],
- ((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
- oh->chunk[old_chunkno].gap) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
-
- /* Set the gap size to zero for the chunk */
- oh->chunk[old_chunkno].gap = 0;
- } /* end if */
- } /* end else */
-
- /* Indicate that we packed messages */
- packed_msg = TRUE;
-
- /* Break out of loop */
- /* (If it's possible to move message to even earlier chunk
- * we'll get it on the next pass - QAK)
- */
- break;
- } /* end if */
- } /* end for */
-
- /* If we packed messages, get out of loop and start over */
- /* (Don't know if this has any benefit one way or the other -QAK) */
- if(packed_msg)
- break;
- } /* end else */
- } /* end for */
-
- /* If we did any packing, remember that */
- if(packed_msg)
- did_packing = TRUE;
- } while(packed_msg);
-
- /* Set return value */
- ret_value = did_packing;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_move_msgs_forward() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_merge_null
- *
- * Purpose: Merge neighboring null messages in an object header
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Oct 10 2005
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5O_merge_null(H5O_t *oh)
-{
- hbool_t merged_msg; /* Flag to indicate that messages were merged */
- hbool_t did_merging = FALSE; /* Whether any messages were merged */
- htri_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_merge_null)
-
- /* check args */
- HDassert(oh != NULL);
-
- /* Loop until no messages merged */
- /* (Double loop is not very efficient, but it would be some extra work to add
- * a list of messages to each chunk -QAK)
- */
- do {
- H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
- unsigned u; /* Local index variable */
-
- /* Reset merged messages flag */
- merged_msg = FALSE;
-
- /* Scan messages for adjacent null messages & merge them */
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- if(H5O_NULL_ID == curr_msg->type->id) {
- H5O_mesg_t *curr_msg2; /* Pointer to current message to operate on */
- unsigned v; /* Local index variable */
-
- /* Should be no gaps in chunk with null message */
- HDassert(oh->chunk[curr_msg->chunkno].gap == 0);
-
- /* Loop over messages again, looking for null message in same chunk */
- for(v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++) {
- if(u != v && H5O_NULL_ID == curr_msg2->type->id && curr_msg->chunkno == curr_msg2->chunkno) {
-
- /* Check for second message after first message */
- if((curr_msg->raw + curr_msg->raw_size) == (curr_msg2->raw - H5O_SIZEOF_MSGHDR_OH(oh))) {
- /* Extend first null message length to cover second null message */
- curr_msg->raw_size += (H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size);
-
- /* Message has been merged */
- merged_msg = TRUE;
- } /* end if */
- /* Check for second message before first message */
- else if((curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)) == (curr_msg2->raw + curr_msg2->raw_size)) {
- /* Adjust first message address and extend length to cover second message */
- curr_msg->raw -= (H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size);
- curr_msg->raw_size += (H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg2->raw_size);
-
- /* Message has been merged */
- merged_msg = TRUE;
- } /* end if */
-
- /* Second message has been merged, delete it */
- if(merged_msg) {
- /* Release any information/memory for second message */
- H5O_free_mesg(curr_msg2);
-
- /* Mark first message as dirty */
- curr_msg->dirty = TRUE;
-
- /* Remove second message from list of messages */
- if(v < (oh->nmesgs - 1))
- HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t));
-
- /* Decrement # of messages */
- /* (Don't bother reducing size of message array for now -QAK) */
- oh->nmesgs--;
-
- /* Get out of loop */
- break;
- } /* end if */
- } /* end if */
- } /* end for */
-
- /* Get out of loop if we merged messages */
- if(merged_msg)
- break;
- } /* end if */
- } /* end for */
-
- /* If we did any merging, remember that */
- if(merged_msg)
- did_merging = TRUE;
- } while(merged_msg);
-
- /* Set return value */
- ret_value = did_merging;
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_merge_null() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_remove_empty_chunks
- *
- * Purpose: Attempt to eliminate empty chunks from object header.
- *
- * This examines a chunk to see if it's empty
- * and removes it (and the continuation message that points to it)
- * from the object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Oct 17 2005
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
-{
- hbool_t deleted_chunk; /* Whether to a chunk was deleted */
- hbool_t did_deleting = FALSE; /* Whether any chunks were deleted */
- htri_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_remove_empty_chunks)
-
- /* check args */
- HDassert(oh != NULL);
-
- /* Loop until no chunks are freed */
- do {
- H5O_mesg_t *null_msg; /* Pointer to null message found */
- H5O_mesg_t *cont_msg; /* Pointer to continuation message found */
- unsigned u, v; /* Local index variables */
-
- /* Reset 'chunk deleted' flag */
- deleted_chunk = FALSE;
-
- /* Scan messages for null messages that fill an entire chunk */
- for(u = 0, null_msg = &oh->mesg[0]; u < oh->nmesgs; u++, null_msg++) {
- /* If a null message takes up an entire object header chunk (and
- * its not the "base" chunk), delete that chunk from object header
- */
- if(H5O_NULL_ID == null_msg->type->id && null_msg->chunkno > 0 &&
- (H5O_SIZEOF_MSGHDR_OH(oh) + null_msg->raw_size)
- == (oh->chunk[null_msg->chunkno].size - H5O_SIZEOF_CHKHDR_OH(oh))) {
- H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
- unsigned null_msg_no; /* Message # for null message */
- unsigned deleted_chunkno; /* Chunk # to delete */
-
- /* Locate continuation message that points to chunk */
- for(v = 0, cont_msg = &oh->mesg[0]; v < oh->nmesgs; v++, cont_msg++) {
- if(H5O_CONT_ID == cont_msg->type->id) {
- /* Decode current continuation message if necessary */
- if(NULL == cont_msg->native) {
- HDassert(H5O_MSG_CONT->decode);
- cont_msg->native = (H5O_MSG_CONT->decode)(f, dxpl_id, cont_msg->raw);
- if(NULL == cont_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
- } /* end if */
-
- /* Check for correct chunk to delete */
- if(oh->chunk[null_msg->chunkno].addr == ((H5O_cont_t *)(cont_msg->native))->addr)
- break;
- } /* end if */
- } /* end for */
- /* Must be a continuation message that points to chunk containing null message */
- HDassert(v < oh->nmesgs);
- HDassert(cont_msg);
-
- /* Initialize information about null message */
- null_msg_no = u;
- deleted_chunkno = null_msg->chunkno;
-
- /* Convert continuation message into a null message */
- if(H5O_release_mesg(f, dxpl_id, oh, cont_msg, TRUE, TRUE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to convert into null message")
-
- /*
- * Remove chunk from object header's data structure
- */
-
- /* Free memory for chunk image */
- H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image);
-
- /* Remove chunk from list of chunks */
- if(null_msg->chunkno < (oh->nchunks - 1))
- HDmemmove(&oh->chunk[null_msg->chunkno], &oh->chunk[null_msg->chunkno + 1], ((oh->nchunks - 1) - null_msg->chunkno) * sizeof(H5O_chunk_t));
-
- /* Decrement # of chunks */
- /* (Don't bother reducing size of chunk array for now -QAK) */
- oh->nchunks--;
-
- /*
- * Delete null message (in empty chunk that was be freed) from list of messages
- */
-
- /* Release any information/memory for message */
- H5O_free_mesg(null_msg);
-
- /* Remove null message from list of messages */
- if(null_msg_no < (oh->nmesgs - 1))
- HDmemmove(&oh->mesg[null_msg_no], &oh->mesg[null_msg_no + 1], ((oh->nmesgs - 1) - null_msg_no) * sizeof(H5O_mesg_t));
-
- /* Decrement # of messages */
- /* (Don't bother reducing size of message array for now -QAK) */
- oh->nmesgs--;
-
- /* Adjust chunk # for messages in chunks after deleted chunk */
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- HDassert(curr_msg->chunkno != deleted_chunkno);
- if(curr_msg->chunkno > deleted_chunkno)
- curr_msg->chunkno--;
- } /* end for */
-
- /* Found chunk to delete */
- deleted_chunk = TRUE;
- break;
- } /* end if */
- } /* end for */
-
- /* If we deleted any chunks, remember that */
- if(deleted_chunk)
- did_deleting = TRUE;
- } while(deleted_chunk);
-
- /* Set return value */
- ret_value = did_deleting;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_remove_empty_chunks() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_condense_header
- *
- * Purpose: Attempt to eliminate empty chunks from object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Oct 4 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
-{
- hbool_t rescan_header; /* Whether to rescan header */
- htri_t result; /* Result from packing/merging/etc */
- herr_t ret_value = SUCCEED; /* return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_condense_header)
-
- /* check args */
- HDassert(oh != NULL);
-
- /* Loop until no changed to the object header messages & chunks */
- do {
- /* Reset 'rescan chunks' flag */
- rescan_header = FALSE;
-
- /* Scan for messages that can be moved earlier in chunks */
- result = H5O_move_msgs_forward(oh);
- if(result < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't move header messages forward")
- if(result > 0)
- rescan_header = TRUE;
-
- /* Scan for adjacent null messages & merge them */
- result = H5O_merge_null(oh);
- if(result < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack null header messages")
- if(result > 0)
- rescan_header = TRUE;
-
- /* Scan for empty chunks to remove */
- result = H5O_remove_empty_chunks(f, oh, dxpl_id);
- if(result < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't remove empty chunk")
- if(result > 0)
- rescan_header = TRUE;
- } while(rescan_header);
-#ifdef H5O_DEBUG
-H5O_assert(oh);
-#endif /* H5O_DEBUG */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_condense_header() */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5O_alloc_extend_chunk
- *
- * Purpose: Attempt to extend a chunk that is allocated on disk.
- *
- * If the extension is successful, and if the last message
- * of the chunk is the null message, then that message will
- * be extended with the chunk. Otherwise a new null message
- * is created.
- *
- * f is the file in which the chunk will be written. It is
- * included to ensure that there is enough space to extend
- * this chunk.
- *
- * Return: TRUE: The chunk has been extended, and *msg_idx
- * contains the message index for null message
- * which is large enough to hold size bytes.
- *
- * FALSE: The chunk cannot be extended, and *msg_idx
- * is undefined.
- *
- * FAIL: Some internal error has been detected.
- *
- * Programmer: John Mainzer -- 8/16/05
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5O_alloc_extend_chunk(H5F_t *f,
- H5O_t *oh,
- unsigned chunkno,
- size_t size,
- unsigned * msg_idx)
-{
- size_t delta; /* Change in chunk's size */
- size_t aligned_size = H5O_ALIGN_OH(oh, size);
- uint8_t *old_image; /* Old address of chunk's image in memory */
- size_t old_size; /* Old size of chunk */
- htri_t tri_result; /* Result from checking if chunk can be extended */
- int extend_msg = -1;/* Index of null message to extend */
- unsigned u; /* Local index variable */
- htri_t ret_value = TRUE; /* return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_extend_chunk)
-
- /* check args */
- HDassert(f != NULL);
- HDassert(oh != NULL);
- HDassert(chunkno < oh->nchunks);
- HDassert(size > 0);
- HDassert(msg_idx != NULL);
- HDassert(H5F_addr_defined(oh->chunk[chunkno].addr));
-
- /* Test to see if the specified chunk ends with a null messages.
- * If successful, set the index of the the null message in extend_msg.
- */
- for(u = 0; u < oh->nmesgs; u++) {
- /* Check for null message at end of proper chunk */
- /* (account for possible checksum at end of chunk) */
- if(oh->mesg[u].chunkno == chunkno && H5O_NULL_ID == oh->mesg[u].type->id &&
- ((oh->mesg[u].raw + oh->mesg[u].raw_size)
- == ((oh->chunk[chunkno].image + oh->chunk[chunkno].size) -
- (oh->chunk[chunkno].gap + H5O_SIZEOF_CHKSUM_OH(oh))))) {
-
- extend_msg = u;
- break;
- } /* end if */
- } /* end for */
-
- /* If we can extend an existing null message, adjust the delta appropriately */
- if(extend_msg >= 0) {
- HDassert(oh->chunk[chunkno].gap == 0);
- delta = aligned_size - oh->mesg[extend_msg].raw_size;
- } /* end if */
- else
- delta = (aligned_size + H5O_SIZEOF_MSGHDR_OH(oh)) - oh->chunk[chunkno].gap;
- delta = H5O_ALIGN_OH(oh, delta);
-
- /* Determine whether the chunk can be extended */
- tri_result = H5MF_can_extend(f, H5FD_MEM_OHDR, oh->chunk[chunkno].addr,
- (hsize_t)(oh->chunk[chunkno].size), (hsize_t)delta);
- if(tri_result == FALSE) /* can't extend -- we are done */
- HGOTO_DONE(FALSE)
- else if(tri_result < 0) /* error */
- HGOTO_ERROR(H5E_RESOURCE, H5E_SYSTEM, FAIL, "can't tell if we can extend chunk")
-
- /* If we get this far, we should be able to extend the chunk */
- if(H5MF_extend(f, H5FD_MEM_OHDR, oh->chunk[chunkno].addr, (hsize_t)(oh->chunk[chunkno].size), (hsize_t)delta) < 0 )
- HGOTO_ERROR(H5E_RESOURCE, H5E_SYSTEM, FAIL, "can't extend chunk")
-
- /* If we can extend an existing null message, take care of that */
- if(extend_msg >= 0) {
- /* Adjust message size of existing null message */
- oh->mesg[extend_msg].dirty = TRUE;
- oh->mesg[extend_msg].raw_size += delta;
- } /* end if */
- /* Create new null message for end of chunk */
- else {
- /* Create a new null message */
- if(oh->nmesgs >= oh->alloc_nmesgs)
- if(H5O_alloc_msgs(oh, (size_t)1) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
-
- /* Set extension message */
- extend_msg = oh->nmesgs++;
-
- /* Initialize new null message */
- oh->mesg[extend_msg].type = H5O_MSG_NULL;
- oh->mesg[extend_msg].dirty = TRUE;
- oh->mesg[extend_msg].native = NULL;
- oh->mesg[extend_msg].raw = ((oh->chunk[chunkno].image + oh->chunk[chunkno].size)
- - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[chunkno].gap))
- + H5O_SIZEOF_MSGHDR_OH(oh);
- oh->mesg[extend_msg].raw_size = (delta + oh->chunk[chunkno].gap) - H5O_SIZEOF_MSGHDR_OH(oh);
- oh->mesg[extend_msg].chunkno = chunkno;
- } /* end else */
-
- /* Allocate more memory space for chunk's image */
- old_image = oh->chunk[chunkno].image;
- old_size = oh->chunk[chunkno].size;
- oh->chunk[chunkno].size += delta;
- oh->chunk[chunkno].image = H5FL_BLK_REALLOC(chunk_image, old_image, oh->chunk[chunkno].size);
- oh->chunk[chunkno].gap = 0;
- oh->chunk[chunkno].dirty = TRUE;
- if(NULL == oh->chunk[chunkno].image)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Wipe new space for chunk */
- HDmemset(oh->chunk[chunkno].image + old_size, 0, oh->chunk[chunkno].size - old_size);
-
- /* Spin through existing messages, adjusting them */
- for(u = 0; u < oh->nmesgs; u++) {
- /* Adjust raw addresses for messages in this chunk to reflect new 'image' address */
- if(oh->mesg[u].chunkno == chunkno)
- oh->mesg[u].raw = oh->chunk[chunkno].image + (oh->mesg[u].raw - old_image);
-
- /* Find continuation message which points to this chunk and adjust chunk's size */
- /* (Chunk 0 doesn't have a continuation message that points to it and
- * it's size is directly encoded in the object header) */
- if(chunkno > 0 && (H5O_CONT_ID == oh->mesg[u].type->id) &&
- (((H5O_cont_t *)(oh->mesg[u].native))->chunkno == chunkno)) {
- /* Adjust size of continuation message */
- HDassert(((H5O_cont_t *)(oh->mesg[u].native))->size == old_size);
- ((H5O_cont_t *)(oh->mesg[u].native))->size = oh->chunk[chunkno].size;
-
- /* Flag continuation message as dirty */
- oh->mesg[u].dirty = TRUE;
- } /* end if */
- } /* end for */
-
- /* Set return value */
- *msg_idx = extend_msg;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_alloc_extend_chunk() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_alloc_new_chunk
- *
- * Purpose: Allocates a new chunk for the object header, including
- * file space.
- *
- * One of the other chunks will get an object continuation
- * message. If there isn't room in any other chunk for the
- * object continuation message, then some message from
- * another chunk is moved into this chunk to make room.
- *
- * SIZE need not be aligned.
- *
- * Return: Success: Index number of the null message for the
- * new chunk. The null message will be at
- * least SIZE bytes not counting the message
- * ID or size fields.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 7 1997
- *
- *-------------------------------------------------------------------------
- */
-static unsigned
-H5O_alloc_new_chunk(H5F_t *f,
- hid_t dxpl_id,
- H5O_t *oh,
- size_t size)
-{
- size_t cont_size; /*continuation message size */
- int found_null = (-1); /*best fit null message */
- int found_attr = (-1); /*best fit attribute message */
- int found_link = (-1); /*best fit link message */
- int found_other = (-1); /*best fit other message */
- unsigned idx; /*message number */
- uint8_t *p = NULL; /*ptr into new chunk */
- H5O_cont_t *cont = NULL; /*native continuation message */
- unsigned chunkno; /* Chunk allocated */
- haddr_t new_chunk_addr;
- unsigned u; /* Local index variable */
- unsigned ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk)
-
- /* check args */
- HDassert(oh);
- HDassert(size > 0);
- size = H5O_ALIGN_OH(oh, size);
-
- /*
- * Find the smallest null message that will hold an object
- * continuation message. Failing that, find the smallest message
- * that could be moved to make room for the continuation message.
- *
- * Don't ever move continuation message from one chunk to another.
- * Prioritize link messages moving to later chunks, instead of
- * more "important" messages.
- * Avoid moving attributes when possible to preserve their
- * ordering (although ordering is *not* guaranteed!).
- *
- */
- cont_size = H5O_ALIGN_OH(oh, H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f));
- for(u = 0; u < oh->nmesgs; u++) {
- int msg_id = oh->mesg[u].type->id; /* Temp. copy of message type ID */
-
- if(H5O_NULL_ID == msg_id) {
- if(cont_size == oh->mesg[u].raw_size) {
- found_null = u;
- break;
- } else if(oh->mesg[u].raw_size >= cont_size &&
- (found_null < 0 ||
- oh->mesg[u].raw_size < oh->mesg[found_null].raw_size)) {
- found_null = u;
- }
- } else if(H5O_CONT_ID == msg_id) {
- /*don't consider continuation messages */
- } else if(H5O_ATTR_ID == msg_id) {
- if(oh->mesg[u].raw_size >= cont_size &&
- (found_attr < 0 ||
- oh->mesg[u].raw_size < oh->mesg[found_attr].raw_size))
- found_attr = u;
- } else if(H5O_LINK_ID == msg_id) {
- if(oh->mesg[u].raw_size >= cont_size &&
- (found_link < 0 ||
- oh->mesg[u].raw_size < oh->mesg[found_link].raw_size))
- found_link = u;
- } else {
- if(oh->mesg[u].raw_size >= cont_size &&
- (found_other < 0 ||
- oh->mesg[u].raw_size < oh->mesg[found_other].raw_size))
- found_other = u;
- } /* end else */
- } /* end for */
- HDassert(found_null >= 0 || found_attr >= 0 || found_link >= 0 || found_other >= 0);
-
- /*
- * If we must move some other message to make room for the null
- * message, then make sure the new chunk has enough room for that
- * other message.
- *
- * Move link messages first, then other messages, and attributes
- * only as a last resort.
- *
- */
- if(found_null < 0) {
- if(found_link >= 0)
- found_other = found_link;
-
- if(found_other < 0)
- found_other = found_attr;
-
- HDassert(found_other >= 0);
- size += H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other].raw_size;
- } /* end if */
-
- /*
- * The total chunk size must include enough space for the checksum
- * on the chunk and the continuation chunk magic #. (which are only present
- * in later versions of the object header)
- */
- size += H5O_SIZEOF_CHKHDR_OH(oh);
-
- /*
- * The total chunk size must include the requested space plus enough
- * for the message header. This must be at least some minimum and a
- * multiple of the alignment size.
- */
- size = MAX(H5O_MIN_SIZE, size + H5O_SIZEOF_MSGHDR_OH(oh));
- HDassert(size == H5O_ALIGN_OH(oh, size));
-
- /* allocate space in file to hold the new chunk */
- new_chunk_addr = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)size);
- if(HADDR_UNDEF == new_chunk_addr)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to allocate space for new chunk")
-
- /*
- * Create the new chunk giving it a file address.
- */
- if(oh->nchunks >= oh->alloc_nchunks) {
- unsigned na = MAX(H5O_NCHUNKS, oh->alloc_nchunks * 2); /* Double # of chunks allocated */
- H5O_chunk_t *x = H5FL_SEQ_REALLOC(H5O_chunk_t, oh->chunk, (size_t)na);
-
- if(!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
- oh->alloc_nchunks = na;
- oh->chunk = x;
- } /* end if */
-
- chunkno = oh->nchunks++;
- oh->chunk[chunkno].dirty = TRUE;
- oh->chunk[chunkno].addr = new_chunk_addr;
- oh->chunk[chunkno].size = size;
- oh->chunk[chunkno].gap = 0;
- if(NULL == (oh->chunk[chunkno].image = p = H5FL_BLK_CALLOC(chunk_image, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
-
- /* If this is a later version of the object header format, put the magic
- * # at the beginning of the chunk image.
- */
- if(oh->version > H5O_VERSION_1) {
- HDmemcpy(p, H5O_CHK_MAGIC, (size_t)H5O_SIZEOF_MAGIC);
- p += H5O_SIZEOF_MAGIC;
- } /* end if */
-
- /*
- * Make sure we have enough space for all possible new messages
- * that could be generated below.
- */
- if(oh->nmesgs + 3 > oh->alloc_nmesgs)
- if(H5O_alloc_msgs(oh, (size_t)3) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
-
- /* Move message (that will be replaced with continuation message)
- * to new chunk, if necessary.
- */
- if(found_null < 0) {
- H5O_mesg_t *null_msg; /* Pointer to new null message */
-
- /* Create null message for space that message to copy currently occupies */
- found_null = oh->nmesgs++;
- null_msg = &(oh->mesg[found_null]);
- null_msg->type = H5O_MSG_NULL;
- null_msg->dirty = TRUE;
- null_msg->native = NULL;
- null_msg->raw = oh->mesg[found_other].raw;
- null_msg->raw_size = oh->mesg[found_other].raw_size;
- null_msg->chunkno = oh->mesg[found_other].chunkno;
-
- /* Copy the message to move to its new location */
- /* (Chunk is already dirty, no need to mark it) */
- HDmemcpy(p, oh->mesg[found_other].raw - H5O_SIZEOF_MSGHDR_OH(oh),
- oh->mesg[found_other].raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
-
- /* Switch message to point to new location */
- oh->mesg[found_other].raw = p + H5O_SIZEOF_MSGHDR_OH(oh);
- oh->mesg[found_other].chunkno = chunkno;
-
- /* Account for copied message in new chunk */
- p += H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other].raw_size;
- size -= H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other].raw_size;
- } /* end if */
- HDassert(found_null >= 0);
-
- /* Create null message for [rest of] space in new chunk */
- /* (account for chunk's magic # & checksum) */
- idx = oh->nmesgs++;
- oh->mesg[idx].type = H5O_MSG_NULL;
- oh->mesg[idx].dirty = TRUE;
- oh->mesg[idx].native = NULL;
- oh->mesg[idx].raw = p + H5O_SIZEOF_MSGHDR_OH(oh);
- oh->mesg[idx].raw_size = size -
- (H5O_SIZEOF_CHKHDR_OH(oh) + H5O_SIZEOF_MSGHDR_OH(oh));
- oh->mesg[idx].chunkno = chunkno;
-
- /* Initialize the continuation information */
- if(NULL == (cont = H5FL_MALLOC(H5O_cont_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
- cont->addr = oh->chunk[chunkno].addr;
- cont->size = oh->chunk[chunkno].size;
- cont->chunkno = chunkno;
-
- /* Split the null message and point at continuation message */
- if(H5O_alloc_null(oh, (unsigned)found_null, H5O_MSG_CONT, cont, cont_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't split null message")
-
- /* Set return value */
- ret_value = idx;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_alloc_new_chunk() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_eliminate_gap
- *
- * Purpose: Eliminate a gap in a chunk with a null message
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Oct 17 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg, uint8_t *gap_loc, size_t gap_size)
-{
- uint8_t *move_start, *move_end; /* Pointers to area of messages to move */
- hbool_t null_before_gap; /* Flag whether the null message is before the gap or not */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_eliminate_gap)
-
- /* check args */
- HDassert(oh);
- HDassert(oh->version > H5O_VERSION_1);
- HDassert(mesg);
- HDassert(gap_loc);
- HDassert(gap_size);
-
- /* Check if the null message is before or after the gap produced */
- null_before_gap = (hbool_t)(mesg->raw < gap_loc);
-
- /* Set up information about region of messages to move */
- if(null_before_gap) {
- move_start = mesg->raw + mesg->raw_size;
- move_end = gap_loc;
- } /* end if */
- else {
- move_start = gap_loc + gap_size;
- move_end = mesg->raw - H5O_SIZEOF_MSGHDR_OH(oh);
- } /* end else */
-
- /* Check for messages between null message and gap */
- if(move_end > move_start) {
- unsigned u; /* Local index variable */
-
- /* Look for messages that need to move, to adjust raw pointers in chunk */
- for(u = 0; u < oh->nmesgs; u++) {
- uint8_t *msg_start; /* Start of encoded message in chunk */
-
- msg_start = oh->mesg[u].raw - H5O_SIZEOF_MSGHDR_OH(oh);
- if(oh->mesg[u].chunkno == mesg->chunkno
- && (msg_start >= move_start && msg_start < move_end)) {
- /* Move message's raw pointer in appropriate direction */
- if(null_before_gap)
- oh->mesg[u].raw += gap_size;
- else
- oh->mesg[u].raw -= gap_size;
- } /* end if */
- } /* end for */
-
- /* Slide raw message info in chunk image */
- if(null_before_gap)
- /* Slide messages down */
- HDmemmove(move_start + gap_size, move_start, (size_t)(move_end - move_start));
- else {
- /* Slide messages up */
- HDmemmove(move_start - gap_size, move_start, (size_t)(move_end - move_start));
-
- /* Adjust start of null message */
- mesg->raw -= gap_size;
- } /* end else */
- } /* end if */
-
- /* Zero out addition to null message */
- HDmemset(mesg->raw + mesg->raw_size, 0, gap_size);
-
- /* Adjust size of null message */
- mesg->raw_size += gap_size;
-
- /* Mark null message as dirty */
- mesg->dirty = TRUE;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5O_eliminate_gap() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_add_gap
- *
- * Purpose: Add a gap to a chunk
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Oct 17 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx,
- uint8_t *new_gap_loc, size_t new_gap_size)
-{
- hbool_t merged_with_null; /* Whether the gap was merged with a null message */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_add_gap)
-
- /* check args */
- HDassert(oh);
- HDassert(oh->version > H5O_VERSION_1);
- HDassert(new_gap_loc);
- HDassert(new_gap_size);
-
- /* Check for existing null message in chunk */
- merged_with_null = FALSE;
- for(u = 0; u < oh->nmesgs && !merged_with_null; u++) {
- /* Find a null message in the chunk with the new gap */
- /* (a null message that's not the one we are eliminating) */
- if(H5O_NULL_ID == oh->mesg[u].type->id && oh->mesg[u].chunkno == chunkno
- && u != idx) {
- /* Sanity check - chunks with null messages shouldn't have a gap */
- HDassert(oh->chunk[chunkno].gap == 0);
-
- /* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, &oh->mesg[u], new_gap_loc, new_gap_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't eliminate gap in chunk")
-
- /* Set flag to indicate that the gap was handled */
- merged_with_null = TRUE;
- } /* end if */
- } /* end for */
-
- /* If we couldn't find a null message in the chunk, move the gap to the end */
- if(!merged_with_null) {
- /* Adjust message offsets after new gap forward in chunk */
- for(u = 0; u < oh->nmesgs; u++)
- if(oh->mesg[u].chunkno == chunkno && oh->mesg[u].raw > new_gap_loc)
- oh->mesg[u].raw -= new_gap_size;
-
- /* Slide raw message info forward in chunk image */
- HDmemmove(new_gap_loc, new_gap_loc + new_gap_size,
- (size_t)((oh->chunk[chunkno].image + (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh))) - (new_gap_loc + new_gap_size)));
-
- /* Add existing gap size to new gap size */
- new_gap_size += oh->chunk[chunkno].gap;
-
- /* Merging with existing gap will allow for a new null message */
- if(new_gap_size >= (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) {
- H5O_mesg_t *null_msg; /* Pointer to new null message */
-
- /* Check if we need to extend message table to hold the new null message */
- if(oh->nmesgs >= oh->alloc_nmesgs)
- if(H5O_alloc_msgs(oh, (size_t)1) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
-
- /* Increment new gap size */
- oh->chunk[chunkno].gap += new_gap_size;
-
- /* Create new null message, with the tail of the previous null message */
- null_msg = &(oh->mesg[oh->nmesgs++]);
- null_msg->type = H5O_MSG_NULL;
- null_msg->dirty = TRUE;
- null_msg->native = NULL;
- null_msg->raw_size = new_gap_size - H5O_SIZEOF_MSGHDR_OH(oh);
- null_msg->raw = (oh->chunk[chunkno].image + oh->chunk[chunkno].size)
- - (H5O_SIZEOF_CHKSUM_OH(oh) + null_msg->raw_size);
- null_msg->chunkno = chunkno;
-
- /* Zero out new null message's raw data */
- if(null_msg->raw_size)
- HDmemset(null_msg->raw, 0, null_msg->raw_size);
-
- /* Reset size of gap in chunk */
- oh->chunk[chunkno].gap = 0;
- } /* end if */
- else
- oh->chunk[chunkno].gap = new_gap_size;
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_add_gap() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_alloc
- *
- * Purpose: Allocate enough space in the object header for this message.
- *
- * Return: Success: Index of message
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 6 1997
- *
- *-------------------------------------------------------------------------
- */
-static unsigned
-H5O_alloc(H5F_t *f,
- hid_t dxpl_id,
- H5O_t *oh,
- const H5O_msg_class_t *type,
- size_t size,
- unsigned * oh_flags_ptr)
-{
- size_t aligned_size = H5O_ALIGN_OH(oh, size);
- unsigned idx; /* Index of message which fits allocation */
- unsigned ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc)
-
- /* check args */
- HDassert(oh);
- HDassert(type);
- HDassert(oh_flags_ptr);
-
- /* look for a null message which is large enough */
- for(idx = 0; idx < oh->nmesgs; idx++)
- if(H5O_NULL_ID == oh->mesg[idx].type->id && oh->mesg[idx].raw_size >= aligned_size)
- break;
-
- /* if we didn't find one, then allocate more header space */
- if(idx >= oh->nmesgs) {
- unsigned chunkno;
-
- /* check to see if we can extend one of the chunks. If we can,
- * do so. Otherwise, we will have to allocate a new chunk.
- *
- * Note that in this new version of this function, all chunks
- * must have file space allocated to them.
- */
- for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
- htri_t tri_result;
-
- HDassert(H5F_addr_defined(oh->chunk[chunkno].addr));
-
- tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, size, &idx);
- if(tri_result == TRUE)
- break;
- else if(tri_result == FALSE)
- idx = UFAIL;
- else
- HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, UFAIL, "H5O_alloc_extend_chunk failed unexpectedly")
- } /* end for */
-
- /* If idx is still UFAIL, we were not able to extend a chunk,
- * create a new one.
- */
- if(idx == UFAIL)
- if((idx = H5O_alloc_new_chunk(f, dxpl_id, oh, size)) == UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "unable to create a new object header data chunk")
- } /* end if */
-
- /* Split the null message and point at continuation message */
- if(H5O_alloc_null(oh, idx, type, NULL, aligned_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't split null message")
-
- /* Mark the object header as modified */
- *oh_flags_ptr |= H5AC__DIRTIED_FLAG;
-
-#ifdef H5O_DEBUG
-H5O_assert(oh);
-#endif /* H5O_DEBUG */
- /* Set return value */
- ret_value = idx;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_alloc() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_raw_size
*
* Purpose: Call the 'raw_size' method for a
@@ -4341,13 +2916,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
{
const H5O_msg_class_t *type; /* Type of object to free */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg)
+ FUNC_ENTER_NOAPI(H5O_delete_mesg, FAIL)
/* Check args */
HDassert(f);
@@ -4355,9 +2930,7 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
/* Get the message to free's type */
if(mesg->flags & H5O_FLAG_SHARED)
- {
type = H5O_MSG_SHARED;
- }
else
type = mesg->type;
@@ -5139,346 +3712,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_mesg_hash() */
-#ifdef H5O_DEBUG
-
-/*-------------------------------------------------------------------------
- * Function: H5O_assert
- *
- * Purpose: Sanity check the information for an object header data
- * structure.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Oct 17 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5O_assert(const H5O_t *oh)
-{
- H5O_mesg_t *curr_msg; /* Pointer to current message to examine */
- H5O_mesg_t *tmp_msg; /* Pointer to temporary message to examine */
- unsigned u, v; /* Local index variables */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_assert)
-
- /* Loop over all chunks in object header */
- for(u = 0; u < oh->nchunks; u++) {
- /* Check for valid raw data image */
- HDassert(oh->chunk[u].image);
- HDassert(oh->chunk[u].size > (size_t)H5O_SIZEOF_CHKHDR_OH(oh));
-
- /* All chunks must be allocated on disk */
- HDassert(H5F_addr_defined(oh->chunk[u].addr));
-
- /* Version specific checks */
- if(oh->version > H5O_VERSION_1) {
- /* Make certain that the magic number is correct for each chunk */
- HDassert(!HDmemcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5O_SIZEOF_MAGIC));
-
- /* Check for valid gap size */
- HDassert(oh->chunk[u].gap < (size_t)H5O_SIZEOF_MSGHDR_OH(oh));
- } /* end if */
- else
- /* Gaps should never occur in version 1 of the format */
- HDassert(oh->chunk[u].gap == 0);
- } /* end for */
-
- /* Loop over all messages in object header */
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- /* Make certain that the message is in a valid chunk */
- HDassert(curr_msg->chunkno < oh->nchunks);
-
- /* Make certain null messages aren't in chunks with gaps */
- if(H5O_NULL_ID == curr_msg->type->id)
- HDassert(oh->chunk[curr_msg->chunkno].gap == 0);
-
- /* Make certain that the message is completely in a chunk message area */
- HDassert(curr_msg->raw_size <= (oh->chunk[curr_msg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap));
- if(curr_msg->chunkno == 0)
- HDassert(curr_msg->raw >= oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_HDR_OH(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
- else
- HDassert(curr_msg->raw >= oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_CHKHDR_OH(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
- HDassert(curr_msg->raw + curr_msg->raw_size <= (oh->chunk[curr_msg->chunkno].image + oh->chunk[curr_msg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap));
-
- /* Make certain that no other messages overlap this message */
- for(v = 0, tmp_msg = &oh->mesg[0]; v < oh->nmesgs; v++, tmp_msg++) {
- if(u != v)
- HDassert(!(tmp_msg->raw >= curr_msg->raw && tmp_msg->raw < (curr_msg->raw + curr_msg->raw_size)));
- } /* end for */
- } /* end for */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5O_assert() */
-#endif /* H5O_DEBUG */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_debug_id
- *
- * Purpose: Act as a proxy for calling the 'debug' method for a
- * particular class of object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 13 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth)
-{
- const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
- herr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5O_debug_id,FAIL)
-
- /* Check args */
- HDassert(type_id < NELMTS(H5O_msg_class_g));
- type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
- HDassert(type);
- HDassert(type->debug);
- HDassert(f);
- HDassert(mesg);
- HDassert(stream);
- HDassert(indent >= 0);
- HDassert(fwidth >= 0);
-
- /* Call the debug method in the class */
- if((ret_value = (type->debug)(f, dxpl_id, mesg, stream, indent, fwidth)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unable to debug message")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_debug_id() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_debug_real
- *
- * Purpose: Prints debugging info about an object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 6 1997
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth)
-{
- unsigned i, chunkno;
- size_t mesg_total = 0, chunk_total = 0;
- int *sequence;
- void *(*decode)(H5F_t*, hid_t, const uint8_t*);
- herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int)=NULL;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5O_debug_real, FAIL)
-
- /* check args */
- HDassert(f);
- HDassert(oh);
- HDassert(H5F_addr_defined(addr));
- HDassert(stream);
- HDassert(indent >= 0);
- HDassert(fwidth >= 0);
-
- /* debug */
- HDfprintf(stream, "%*sObject Header...\n", indent, "");
-
- HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
- "Dirty:",
- oh->cache_info.is_dirty);
- HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Version:",
- oh->version);
- HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Header size (in bytes):",
- (unsigned)H5O_SIZEOF_HDR_OH(oh));
- HDfprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
- "Number of links:",
- oh->nlink);
- HDfprintf(stream, "%*s%-*s %Zu (%Zu)\n", indent, "", fwidth,
- "Number of messages (allocated):",
- oh->nmesgs, oh->alloc_nmesgs);
- HDfprintf(stream, "%*s%-*s %Zu (%Zu)\n", indent, "", fwidth,
- "Number of chunks (allocated):",
- oh->nchunks, oh->alloc_nchunks);
-
- /* debug each chunk */
- for(i = 0, chunk_total = 0; i < oh->nchunks; i++) {
- size_t chunk_size;
-
- chunk_total += oh->chunk[i].size;
- HDfprintf(stream, "%*sChunk %d...\n", indent, "", i);
-
- HDfprintf(stream, "%*s%-*s %t\n", indent + 3, "", MAX(0, fwidth - 3),
- "Dirty:",
- oh->chunk[i].dirty);
-
- HDfprintf(stream, "%*s%-*s %a\n", indent + 3, "", MAX(0, fwidth - 3),
- "Address:",
- oh->chunk[i].addr);
-
- if(0 == i) {
- if(H5F_addr_ne(oh->chunk[i].addr, addr))
- HDfprintf(stream, "*** WRONG ADDRESS!\n");
- chunk_size = oh->chunk[i].size - H5O_SIZEOF_HDR_OH(oh);
- } /* end if */
- else
- chunk_size = oh->chunk[i].size;
- HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
- "Size in bytes:",
- chunk_size);
-
- HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
- "Gap:",
- oh->chunk[i].gap);
- } /* end for */
-
- /* debug each message */
- if(NULL == (sequence = H5MM_calloc(NELMTS(H5O_msg_class_g) * sizeof(int))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- for(i = 0, mesg_total = 0; i < oh->nmesgs; i++) {
- mesg_total += H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[i].raw_size;
- HDfprintf(stream, "%*sMessage %d...\n", indent, "", i);
-
- /* check for bad message id */
- if(oh->mesg[i].type->id >= (int)NELMTS(H5O_msg_class_g)) {
- HDfprintf(stream, "*** BAD MESSAGE ID 0x%04x\n",
- oh->mesg[i].type->id);
- continue;
- } /* end if */
-
- /* message name and size */
- HDfprintf(stream, "%*s%-*s 0x%04x `%s' (%d)\n",
- indent + 3, "", MAX(0, fwidth - 3),
- "Message ID (sequence number):",
- (unsigned) (oh->mesg[i].type->id),
- oh->mesg[i].type->name,
- sequence[oh->mesg[i].type->id]++);
- HDfprintf (stream, "%*s%-*s %t\n", indent+3, "", MAX (0, fwidth-3),
- "Dirty:",
- oh->mesg[i].dirty);
- HDfprintf (stream, "%*s%-*s %s\n", indent+3, "", MAX (0, fwidth-3),
- "Shared:",
- (oh->mesg[i].flags & H5O_FLAG_SHARED) ? "Yes" : "No");
- HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", MAX(0, fwidth - 3),
- "Constant:",
- (oh->mesg[i].flags & H5O_FLAG_CONSTANT) ? "Yes" : "No");
- if(oh->mesg[i].flags & ~H5O_FLAG_BITS) {
- HDfprintf (stream, "%*s%-*s 0x%02x\n", indent+3,"",MAX(0,fwidth-3),
- "*** ADDITIONAL UNKNOWN FLAGS --->",
- oh->mesg[i].flags & ~H5O_FLAG_BITS);
- } /* end if */
- HDfprintf(stream, "%*s%-*s %Zu bytes\n", indent+3, "", MAX(0,fwidth-3),
- "Raw size in obj header:",
- oh->mesg[i].raw_size);
- HDfprintf(stream, "%*s%-*s %u\n", indent + 3, "", MAX(0, fwidth - 3),
- "Chunk number:",
- oh->mesg[i].chunkno);
- chunkno = oh->mesg[i].chunkno;
- if(chunkno >= oh->nchunks)
- HDfprintf(stream, "*** BAD CHUNK NUMBER\n");
- HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
- "Raw data offset in chunk:",
- (size_t)(oh->mesg[i].raw - oh->chunk[chunkno].image));
-
- /* check the size */
- if((oh->mesg[i].raw + oh->mesg[i].raw_size >
- oh->chunk[chunkno].image + oh->chunk[chunkno].size) ||
- (oh->mesg[i].raw < oh->chunk[chunkno].image))
- HDfprintf(stream, "*** BAD MESSAGE RAW ADDRESS\n");
-
- /* decode the message */
- if(oh->mesg[i].flags & H5O_FLAG_SHARED) {
- decode = H5O_MSG_SHARED->decode;
- debug = H5O_MSG_SHARED->debug;
- } else {
- decode = oh->mesg[i].type->decode;
- debug = oh->mesg[i].type->debug;
- } /* end else */
- if(NULL==oh->mesg[i].native && decode)
- oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw);
- if(NULL == oh->mesg[i].native)
- debug = NULL;
-
- /* print the message */
- HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
- "Message Information:");
- if(debug)
- (debug)(f, dxpl_id, oh->mesg[i].native, stream, indent + 6, MAX(0, fwidth - 6));
- else
- HDfprintf(stream, "%*s<No info for this message>\n", indent + 6, "");
-
- /* If the message is shared then also print the pointed-to message */
- if(oh->mesg[i].flags & H5O_FLAG_SHARED) {
- H5O_shared_t *shared = (H5O_shared_t*)(oh->mesg[i].native);
- void *mesg;
-
- mesg = H5O_shared_read(f, dxpl_id, shared, oh->mesg[i].type, NULL);
- if(oh->mesg[i].type->debug)
- (oh->mesg[i].type->debug)(f, dxpl_id, mesg, stream, indent + 3, MAX (0, fwidth - 3));
- H5O_free_real(oh->mesg[i].type, mesg);
- } /* end if */
- } /* end for */
- sequence = H5MM_xfree(sequence);
-
- if(mesg_total != chunk_total)
- HDfprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_debug_real() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_debug
- *
- * Purpose: Prints debugging info about an object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 6 1997
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
-{
- H5O_t *oh = NULL;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5O_debug, FAIL)
-
- /* check args */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(stream);
- HDassert(indent >= 0);
- HDassert(fwidth >= 0);
-
- if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
-
- /* debug */
- H5O_debug_real(f, dxpl_id, oh, addr, stream, indent, fwidth);
-
-done:
- if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_debug() */
-