From 2757f75317a07422c9a1d0378f969c3eb802c3a0 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 1 May 2007 16:00:52 -0500 Subject: [svn-r13721] Description: Add "fail if unknown" and "mark if unknown" flags to object header messages. This gives the library a clean way to tell older libraries that a message should not be just ignored if it's unknown, but that other actions should occur. Tested on: Mac OS X/32 10.4.9 (amazon) FreeBSD/32 6.2 (duty) FreeBSD/64 6.2 (liberty) Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2) --- MANIFEST | 4 +- src/H5D.c | 25 ++++- src/H5O.c | 70 ++---------- src/H5Obogus.c | 58 +++++----- src/H5Ocache.c | 161 +++++++++++++++++++-------- src/H5Ocopy.c | 1 - src/H5Odbg.c | 62 ++++++++--- src/H5Omessage.c | 8 +- src/H5Opkg.h | 7 +- src/H5Oprivate.h | 23 +++- src/H5Otest.c | 65 ++++++++++- src/H5Ounknown.c | 89 +++++++++++++++ src/Makefile.am | 2 +- src/Makefile.in | 5 +- test/Makefile.am | 2 +- test/Makefile.in | 16 ++- test/gen_bogus.c | 100 +++++++++++++++++ test/ohdr.c | 327 +++++++++++++++++++++++++++++++------------------------ test/tbogus.h5 | Bin 2052 -> 1944 bytes 19 files changed, 696 insertions(+), 329 deletions(-) create mode 100644 src/H5Ounknown.c create mode 100644 test/gen_bogus.c diff --git a/MANIFEST b/MANIFEST index 7eb873f..5bfd060 100644 --- a/MANIFEST +++ b/MANIFEST @@ -620,6 +620,7 @@ ./src/H5Oshmesg.c ./src/H5Ostab.c ./src/H5Otest.c +./src/H5Ounknown.c ./src/H5P.c ./src/H5Pacpl.c ./src/H5Pdcpl.c @@ -744,7 +745,8 @@ ./test/fillval.c ./test/flush1.c ./test/flush2.c -./test/gen_cross.c +./test/gen_bogus.c _DO_NOT_DISTRIBUTE_ +./test/gen_cross.c _DO_NOT_DISTRIBUTE_ ./test/gen_deflate.c _DO_NOT_DISTRIBUTE_ ./test/gen_mergemsg.c _DO_NOT_DISTRIBUTE_ ./test/gen_new_array.c _DO_NOT_DISTRIBUTE_ diff --git a/src/H5D.c b/src/H5D.c index 0677784..776a2ae 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -1228,11 +1228,26 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout") #ifdef H5O_ENABLE_BOGUS - /* - * Add a "bogus" message (for error testing). - */ - if(H5O_bogus_oh(file, dxpl_id, oh)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update 'bogus' message") +{ + H5P_genplist_t *dc_plist; /* Dataset's creation property list */ + + /* Get dataset's property list object */ + if(NULL == (dc_plist = H5I_object(dset->shared->dcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list") + + /* Check whether to add a "bogus" message */ + if(H5P_exist_plist(dc_plist, H5O_BOGUS_MSG_FLAGS_NAME) > 0) { + uint8_t bogus_flags = 0; /* Flags for creating "bogus" message */ + + /* Retrieve "bogus" message flags */ + if(H5P_get(dc_plist, H5O_BOGUS_MSG_FLAGS_NAME, &bogus_flags) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get bogus message options") + + /* Add a "bogus" message (for error testing). */ + if(H5O_bogus_oh(file, dxpl_id, oh, (unsigned)bogus_flags) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create 'bogus' message") + } /* end if */ +} #endif /* H5O_ENABLE_BOGUS */ /* Add a modification time message. */ diff --git a/src/H5O.c b/src/H5O.c index 2bb7505..b529682 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -104,6 +104,7 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = { H5O_MSG_DRVINFO, /*0x0014 Driver info settings */ H5O_MSG_AINFO, /*0x0015 Attribute information */ H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */ + H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */ }; /* Header object ID to class mapping */ @@ -1315,12 +1316,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh) +H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags) { - int idx; - herr_t ret_value = SUCCEED; /* Return value */ + unsigned idx; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER(H5O_bogus_oh, FAIL) + FUNC_ENTER_NOAPI(H5O_bogus_oh, FAIL) HDassert(f); HDassert(oh); @@ -1333,7 +1334,6 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh) /* Create a new message */ if(idx == oh->nmesgs) { H5O_bogus_t *bogus; /* Pointer to the bogus information */ - unsigned mesg_flags = 0; /* Flags for message in object header */ /* Allocate the native message in memory */ if(NULL == (bogus = H5MM_malloc(sizeof(H5O_bogus_t)))) @@ -1349,65 +1349,17 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh) /* Point to "bogus" information (take it over) */ oh->mesg[idx].native = bogus; - /* Mark the message and object header as dirty */ + /* Set the appropriate flags for the message */ oh->mesg[idx].flags = mesg_flags; + + /* Mark the message and object header as dirty */ oh->mesg[idx].dirty = TRUE; - oh->dirty = TRUE; + oh->cache_info.is_dirty = TRUE; } /* end if */ done: - FUNC_LEAVE(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_bogus_oh() */ - - -/*------------------------------------------------------------------------- - * Function: H5O_bogus - * - * Purpose: Create a "bogus" message in an object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * - * Tuesday, January 21, 2003 - * - *------------------------------------------------------------------------- - */ -herr_t -H5O_bogus(H5O_loc_t *loc, hid_t dxpl_id) -{ - H5O_t *oh = NULL; - unsigned oh_flags = H5AC__NO_FLAGS_SET; - herr_t ret_value = SUCCEED; - - FUNC_ENTER(H5O_bogus, FAIL) - - /* check args */ - HDassert(loc); - HDassert(loc->file); - HDassert(H5F_addr_defined(loc->addr)); - - /* Verify write access to the file */ - if(0 == (H5F_INTENT(loc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") - - /* Get the object header */ - if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") - - /* Create the "bogus" message */ - if(H5O_bogus_oh(ent->file, dxpl_id, oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object 'bogus' message") - - /* Mark object header as changed */ - oh_flags |= H5AC__DIRTIED_FLAG; - -done: - if(oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0) - HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") - - FUNC_LEAVE(ret_value) -} /* end H5O_bogus() */ #endif /* H5O_ENABLE_BOGUS */ @@ -1982,7 +1934,7 @@ H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) } /* end for */ /* Sanity check that all the bytes are accounted for */ - HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg + oh->skipped_mesg_size)); + HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg)); done: if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) diff --git a/src/H5Obogus.c b/src/H5Obogus.c index 488758b..4def755 100644 --- a/src/H5Obogus.c +++ b/src/H5Obogus.c @@ -86,37 +86,37 @@ const H5O_msg_class_t H5O_MSG_BOGUS[1] = {{ *------------------------------------------------------------------------- */ static void * -H5O_bogus_decode(H5F_t UNUSED *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, +H5O_bogus_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, const uint8_t *p) { H5O_bogus_t *mesg = NULL; void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_bogus_decode); + FUNC_ENTER_NOAPI_NOINIT(H5O_bogus_decode) /* check args */ - assert(f); - assert(p); + HDassert(f); + HDassert(p); /* Allocate the bogus message */ - if (NULL==(mesg = H5MM_calloc(sizeof(H5O_bogus_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + if(NULL == (mesg = H5MM_calloc(sizeof(H5O_bogus_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* decode */ UINT32DECODE(p, mesg->u); /* Validate the bogus info */ - if(mesg->u!=H5O_BOGUS_VALUE) - HGOTO_ERROR (H5E_OHDR, H5E_BADVALUE, NULL, "invalid bogus value :-)"); + if(mesg->u != H5O_BOGUS_VALUE) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid bogus value :-)") /* Set return value */ - ret_value=mesg; + ret_value = mesg; done: - if(ret_value==NULL && mesg!=NULL) + if(ret_value == NULL && mesg != NULL) H5MM_xfree(mesg); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_bogus_decode() */ @@ -136,17 +136,17 @@ done: static herr_t H5O_bogus_encode(H5F_t UNUSED *f, hbool_t UNUSED disable_shared, uint8_t *p, const void UNUSED *mesg) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_encode); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_encode) /* check args */ - assert(f); - assert(p); - assert(mesg); + HDassert(f); + HDassert(p); + HDassert(mesg); /* encode */ UINT32ENCODE(p, H5O_BOGUS_VALUE); - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_bogus_encode() */ @@ -171,12 +171,9 @@ H5O_bogus_encode(H5F_t UNUSED *f, hbool_t UNUSED disable_shared, uint8_t *p, con static size_t H5O_bogus_size(const H5F_t UNUSED *f, hbool_t UNUSED disable_shared, const void UNUSED *mesg) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_size); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_size) - /* check args */ - assert(f); - - FUNC_LEAVE_NOAPI(4); + FUNC_LEAVE_NOAPI(4) } /* end H5O_bogus_size() */ @@ -201,20 +198,19 @@ H5O_bogus_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * { const H5O_bogus_t *mesg = (const H5O_bogus_t *)_mesg; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_name_debug); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_debug) /* check args */ - assert(f); - assert(mesg); - assert(stream); - assert(indent >= 0); - assert(fwidth >= 0); + HDassert(f); + HDassert(mesg); + HDassert(stream); + HDassert(indent >= 0); + HDassert(fwidth >= 0); - fprintf(stream, "%*s%-*s `%u'\n", indent, "", fwidth, + HDfprintf(stream, "%*s%-*s `%u'\n", indent, "", fwidth, "Bogus Value:", mesg->u); - FUNC_LEAVE_NOAPI(SUCCEED); -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_bogus_debug() */ #endif /* H5O_ENABLE_BOGUS */ - diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 75f9d69..d574fe8 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -30,6 +30,7 @@ #define H5O_PACKAGE /*suppress error about including H5Opkg */ + /***********/ /* Headers */ /***********/ @@ -38,6 +39,7 @@ #include "H5FLprivate.h" /* Free lists */ #include "H5Opkg.h" /* Object headers */ + /****************/ /* Local Macros */ /****************/ @@ -80,6 +82,9 @@ static herr_t H5O_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr); /* Library Private Variables */ /*****************************/ +/* Declare external the free list for H5O_unknown_t's */ +H5FL_EXTERN(H5O_unknown_t); + /*******************/ /* Local Variables */ @@ -126,15 +131,22 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh) for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { if(curr_msg->dirty) { uint8_t *p; /* Temporary pointer to encode with */ + unsigned msg_id; /* ID for message */ /* Point into message's chunk's image */ p = curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh); + /* Retrieve actual message ID, for unknown messages */ + if(curr_msg->type == H5O_MSG_UNKNOWN) + msg_id = *(H5O_unknown_t *)(curr_msg->native); + else + msg_id = (uint8_t)curr_msg->type->id; + /* Encode the message prefix */ if(oh->version == H5O_VERSION_1) - UINT16ENCODE(p, curr_msg->type->id) + UINT16ENCODE(p, msg_id) else - *p++ = (uint8_t)curr_msg->type->id; + *p++ = (uint8_t)msg_id; HDassert(curr_msg->raw_size < H5O_MESG_MAX_SIZE); UINT16ENCODE(p, curr_msg->raw_size); *p++ = curr_msg->flags; @@ -155,12 +167,16 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh) #ifndef NDEBUG /* Make certain that null messages aren't in chunks w/gaps */ - if(H5O_NULL_ID == curr_msg->type->id) + if(H5O_NULL_ID == msg_id) HDassert(oh->chunk[curr_msg->chunkno].gap == 0); + + /* Unknown messages should always have a native pointer */ + if(curr_msg->type == H5O_MSG_UNKNOWN) + HDassert(curr_msg->native); #endif /* NDEBUG */ - /* Encode the message itself */ - if(curr_msg->native) { + /* Encode the message itself, if it's not an "unknown" message */ + if(curr_msg->native && curr_msg->type != H5O_MSG_UNKNOWN) { /* * Encode the message. If the message is shared then we * encode a Shared Object message instead of the object @@ -226,7 +242,6 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, size_t prefix_size; /* Size of object header prefix */ unsigned nmesgs; /* Total # of messages in this object header */ unsigned curmesg = 0; /* Current message being decoded in object header */ - unsigned skipped_msgs = 0; /* Number of unknown messages skipped */ unsigned merged_null_msgs = 0; /* Number of null messages merged together */ haddr_t chunk_addr; /* Address of first chunk */ size_t chunk_size; /* Size of first chunk */ @@ -474,12 +489,24 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, else id = *p++; + /* Check for unknown message ID getting encoded in file */ + if(id == H5O_UNKNOWN_ID) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "'unknown' message ID encoded in file?!?") + /* Message size */ UINT16DECODE(p, mesg_size); HDassert(mesg_size == H5O_ALIGN_OH(oh, mesg_size)); /* Message flags */ flags = *p++; + if(flags & ~H5O_MSG_FLAG_BITS) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown flag for message") + if((flags & H5O_MSG_FLAG_SHARED) && (flags & H5O_MSG_FLAG_DONTSHARE)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag combination for message") + if((flags & H5O_MSG_FLAG_WAS_UNKNOWN) && (flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag combination for message") + if((flags & H5O_MSG_FLAG_WAS_UNKNOWN) && !(flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag combination for message") /* Reserved bytes/creation index */ if(oh->version == H5O_VERSION_1) @@ -496,51 +523,89 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, if(p + mesg_size > eom_ptr) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header") - /* Skip header messages we don't know about */ - /* (Usually from future versions of the library) */ - if(id >= NELMTS(H5O_msg_class_g) || NULL == H5O_msg_class_g[id]) { - /* Increment the size of the message skipped over (for later sanity checking) */ - oh->skipped_mesg_size += H5O_SIZEOF_MSGHDR_OH(oh) + mesg_size; - - /* Increment skipped messages counter */ - skipped_msgs++; - } /* end if */ - else { #ifndef NDEBUG - /* Increment count of null messages */ - if(H5O_NULL_ID == id) - nullcnt++; + /* Increment count of null messages */ + if(H5O_NULL_ID == id) + nullcnt++; #endif /* NDEBUG */ - /* Check for combining two adjacent 'null' messages */ - if((H5F_get_intent(f) & H5F_ACC_RDWR) && - H5O_NULL_ID == id && oh->nmesgs > 0 && - H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id && - oh->mesg[oh->nmesgs - 1].chunkno == chunkno) { - - /* Combine adjacent null messages */ - mesgno = oh->nmesgs - 1; - oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR_OH(oh) + mesg_size; - oh->mesg[mesgno].dirty = TRUE; - merged_null_msgs++; + /* Check for combining two adjacent 'null' messages */ + if((H5F_get_intent(f) & H5F_ACC_RDWR) && + H5O_NULL_ID == id && oh->nmesgs > 0 && + H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id && + oh->mesg[oh->nmesgs - 1].chunkno == chunkno) { + + /* Combine adjacent null messages */ + mesgno = oh->nmesgs - 1; + oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR_OH(oh) + mesg_size; + oh->mesg[mesgno].dirty = TRUE; + merged_null_msgs++; + } /* end if */ + else { + /* Check if we need to extend message table to hold the new message */ + if(oh->nmesgs >= oh->alloc_nmesgs) + if(H5O_alloc_msgs(oh, (size_t)1) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate more space for messages") + + /* Get index for message */ + mesgno = oh->nmesgs++; + + /* Initialize information about message */ + oh->mesg[mesgno].dirty = FALSE; + oh->mesg[mesgno].flags = flags; + oh->mesg[mesgno].crt_idx = crt_idx; + oh->mesg[mesgno].native = NULL; + oh->mesg[mesgno].raw = (uint8_t *)p; /* Casting away const OK - QAK */ + oh->mesg[mesgno].raw_size = mesg_size; + oh->mesg[mesgno].chunkno = chunkno; + + /* Point unknown messages at 'unknown' message class */ + /* (Usually from future versions of the library) */ + if(id >= NELMTS(H5O_msg_class_g) || NULL == H5O_msg_class_g[id]) { + H5O_unknown_t *unknown; /* Pointer to "unknown" message info */ + + /* Allocate "unknown" message info */ + if(NULL == (unknown = H5FL_MALLOC(H5O_unknown_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Save the original message type ID */ + *unknown = id; + + /* Save 'native' form of continuation message */ + oh->mesg[mesgno].native = unknown; + + /* Set message to "unknown" class */ + oh->mesg[mesgno].type = H5O_msg_class_g[H5O_UNKNOWN_ID]; + + /* Check for "fail if unknown" message flag */ + if(flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, "unknown message with 'fail if unknown' flag found") + /* Check for "mark if unknown" message flag, etc. */ + else if((flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN) && + !(flags & H5O_MSG_FLAG_WAS_UNKNOWN) && + (H5F_get_intent(f) & H5F_ACC_RDWR)) { + + /* Mark the message as "unknown" */ + /* This is a bit aggressive, since the application may + * never change anything about the object (metadata or + * raw data), but we can sort out the finer details + * when/if we start using the flag - QAK + */ + /* Also, it's possible that this functionality may not + * get invoked if the object header is brought into + * the metadata cache in some other "weird" way, like + * using H5Ocopy() - QAK + */ + oh->mesg[mesgno].flags |= H5O_MSG_FLAG_WAS_UNKNOWN; + + /* Mark the message and object header as dirty */ + oh->mesg[mesgno].dirty = TRUE; + oh->cache_info.is_dirty = TRUE; + } /* end if */ } /* end if */ - else { - /* Check if we need to extend message table to hold the new message */ - if(oh->nmesgs >= oh->alloc_nmesgs) - if(H5O_alloc_msgs(oh, (size_t)1) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate more space for messages") - - /* Record information about message */ - mesgno = oh->nmesgs++; + else + /* Set message class for "known" messages */ oh->mesg[mesgno].type = H5O_msg_class_g[id]; - oh->mesg[mesgno].dirty = FALSE; - oh->mesg[mesgno].flags = flags; - oh->mesg[mesgno].crt_idx = crt_idx; - oh->mesg[mesgno].native = NULL; - oh->mesg[mesgno].raw = (uint8_t *)p; /* Casting away const OK - QAK */ - oh->mesg[mesgno].raw_size = mesg_size; - oh->mesg[mesgno].chunkno = chunkno; - } /* end else */ } /* end else */ /* Advance decode pointer past message */ @@ -632,7 +697,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* Sanity check for the correct # of messages in object header */ if(oh->version == H5O_VERSION_1) - if((oh->nmesgs + skipped_msgs + merged_null_msgs) != nmesgs) + if((oh->nmesgs + merged_null_msgs) != nmesgs) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too few messages") #ifdef H5O_DEBUG @@ -645,7 +710,7 @@ H5O_assert(oh); done: /* Release the [possibly partially initialized] object header on errors */ if(!ret_value && oh) - if(H5O_dest(f,oh) < 0) + if(H5O_dest(f, oh) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to destroy object header data") FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 5549cd6..71d4c0a 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -341,7 +341,6 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Initialize header information */ oh_dst->version = oh_src->version; oh_dst->flags = oh_src->flags; - oh_dst->skipped_mesg_size = oh_src->skipped_mesg_size; oh_dst->link_msgs_seen = oh_src->link_msgs_seen; oh_dst->attr_msgs_seen = oh_src->attr_msgs_seen; oh_dst->sizeof_size = H5F_SIZEOF_SIZE(oloc_dst->file); diff --git a/src/H5Odbg.c b/src/H5Odbg.c index 108ac81..c73360f 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -207,7 +207,7 @@ H5O_assert(const H5O_t *oh) HDassert(oh->nchunks == (cont_msgs_found + 1)); /* Sanity check that all the bytes are accounted for */ - HDassert(hdr_size == (free_space + meta_space + mesg_space + oh->skipped_mesg_size)); + HDassert(hdr_size == (free_space + meta_space + mesg_space)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_assert() */ @@ -427,31 +427,57 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i (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), + 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_MSG_FLAG_SHARED) ? "Yes" : "No"); - HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", MAX(0, fwidth - 3), - "Constant:", - (oh->mesg[i].flags & H5O_MSG_FLAG_CONSTANT) ? "Yes" : "No"); - if(oh->mesg[i].flags & ~H5O_MSG_FLAG_BITS) - HDfprintf(stream, "%*s%-*s 0x%02x\n", indent+3,"",MAX(0,fwidth-3), - "*** ADDITIONAL UNKNOWN FLAGS --->", - oh->mesg[i].flags & ~H5O_MSG_FLAG_BITS); - 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 ", indent + 3, "", MAX (0, fwidth - 3), + "Message flags:"); + if(oh->mesg[i].flags) { + hbool_t flag_printed = FALSE; + + if(oh->mesg[i].flags & H5O_MSG_FLAG_SHARED) { + HDfprintf(stream, "%s%s", (flag_printed ? ", " : "<"), "S"); + flag_printed = TRUE; + } /* end if */ + if(oh->mesg[i].flags & H5O_MSG_FLAG_CONSTANT) { + HDfprintf(stream, "%s%s", (flag_printed ? ", " : "<"), "C"); + flag_printed = TRUE; + } /* end if */ + if(oh->mesg[i].flags & H5O_MSG_FLAG_DONTSHARE) { + HDfprintf(stream, "%s%s", (flag_printed ? ", " : "<"), "DS"); + flag_printed = TRUE; + } /* end if */ + if(oh->mesg[i].flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN) { + HDfprintf(stream, "%s%s", (flag_printed ? ", " : "<"), "FIU"); + flag_printed = TRUE; + } /* end if */ + if(oh->mesg[i].flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN) { + HDfprintf(stream, "%s%s", (flag_printed ? ", " : "<"), "MIU"); + flag_printed = TRUE; + } /* end if */ + if(oh->mesg[i].flags & H5O_MSG_FLAG_WAS_UNKNOWN) { + HDassert(oh->mesg[i].flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN); + HDfprintf(stream, "%s%s", (flag_printed ? ", " : "<"), "WU"); + flag_printed = TRUE; + } /* end if */ + HDfprintf(stream, ">\n"); + if(oh->mesg[i].flags & ~H5O_MSG_FLAG_BITS) + HDfprintf(stream, "%*s%-*s 0x%02x\n", indent + 3,"", MAX(0, fwidth - 3), + "*** ADDITIONAL UNKNOWN FLAGS --->", + oh->mesg[i].flags & ~H5O_MSG_FLAG_BITS); + } /* end if */ + else + HDfprintf(stream, "\n"); 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)); + HDfprintf(stream, "%*s%-*s (%Zu, %Zu) bytes\n", indent + 3, "", MAX(0, fwidth - 3), + "Raw message data (offset, size) in chunk:", + (size_t)(oh->mesg[i].raw - oh->chunk[chunkno].image), + oh->mesg[i].raw_size); /* check the size */ if((oh->mesg[i].raw + oh->mesg[i].raw_size > diff --git a/src/H5Omessage.c b/src/H5Omessage.c index a8b332b..a6e13b0 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -340,7 +340,7 @@ H5O_msg_write_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *ty /* Locate message of correct type */ for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) - if(type->id == idx_msg->type->id) + if(type == idx_msg->type) break; if(idx == oh->nmesgs) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found") @@ -482,7 +482,7 @@ H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, /* Scan through the messages looking for the right one */ for(idx = 0; idx < oh->nmesgs; idx++) - if(type_id == oh->mesg[idx].type->id) + if(type == oh->mesg[idx].type) break; if(idx == oh->nmesgs) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "message type not found") @@ -879,7 +879,7 @@ H5O_msg_exists_oh(const H5O_t *oh, unsigned type_id) /* Scan through the messages looking for the right one */ for(u = 0; u < oh->nmesgs; u++) - if(type->id == oh->mesg[u].type->id) + if(type == oh->mesg[u].type) HGOTO_DONE(TRUE) done: @@ -1242,7 +1242,7 @@ H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, /* Iterate over messages */ for(sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs && !ret_value; idx++, idx_msg++) { - if(type->id == idx_msg->type->id) { + if(type == idx_msg->type) { /* Decode the message if necessary. */ H5O_LOAD_NATIVE(f, dxpl_id, idx_msg, FAIL) diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 067e36c..a999638 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -30,7 +30,7 @@ #define H5O_NMESGS 8 /*initial number of messages */ #define H5O_NCHUNKS 2 /*initial number of chunks */ #define H5O_MIN_SIZE 22 /* Min. obj header data size (must be big enough for a message prefix and a continuation message) */ -#define H5O_MSG_TYPES 23 /* # of types of messages */ +#define H5O_MSG_TYPES 24 /* # of types of messages */ #define H5O_MAX_CRT_ORDER_IDX 65535 /* Max. creation order index value */ /* Versions of object header structure */ @@ -265,7 +265,6 @@ struct H5O_t { size_t nmesgs; /*number of messages */ size_t alloc_nmesgs; /*number of message slots */ H5O_mesg_t *mesg; /*array of messages */ - size_t skipped_mesg_size; /*size of skipped messages (for sanity checking) */ size_t link_msgs_seen; /* # of link messages seen when loading header */ size_t attr_msgs_seen; /* # of attribute messages seen when loading header */ @@ -440,6 +439,9 @@ H5_DLLVAR const H5O_msg_class_t H5O_MSG_AINFO[1]; /* Reference Count Message. (0x0016) */ H5_DLLVAR const H5O_msg_class_t H5O_MSG_REFCOUNT[1]; +/* Placeholder for unknown message. (0x0017) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_UNKNOWN[1]; + /* * Object header "object" types @@ -523,6 +525,7 @@ H5_DLL htri_t H5O_is_attr_empty_test(hid_t oid); H5_DLL htri_t H5O_is_attr_dense_test(hid_t oid); H5_DLL herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs); H5_DLL herr_t H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count); +H5_DLL herr_t H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val); #endif /* H5O_TESTING */ /* Object header debugging routines */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index f904c4c..0689838 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -71,8 +71,9 @@ typedef struct H5O_t H5O_t; #define H5O_MSG_FLAG_SHARED 0x02u #define H5O_MSG_FLAG_DONTSHARE 0x04u #define H5O_MSG_FLAG_FAIL_IF_UNKNOWN 0x08u -#define H5O_MSG_FLAG_CURRENT 0x10u -#define H5O_MSG_FLAG_BITS (H5O_MSG_FLAG_CONSTANT|H5O_MSG_FLAG_SHARED|H5O_MSG_FLAG_DONTSHARE) +#define H5O_MSG_FLAG_MARK_IF_UNKNOWN 0x10u +#define H5O_MSG_FLAG_WAS_UNKNOWN 0x20u +#define H5O_MSG_FLAG_BITS (H5O_MSG_FLAG_CONSTANT|H5O_MSG_FLAG_SHARED|H5O_MSG_FLAG_DONTSHARE|H5O_MSG_FLAG_FAIL_IF_UNKNOWN|H5O_MSG_FLAG_MARK_IF_UNKNOWN|H5O_MSG_FLAG_WAS_UNKNOWN) /* Flags for updating messages */ #define H5O_UPDATE_TIME 0x01u @@ -84,6 +85,10 @@ typedef struct H5O_t H5O_t; #define H5O_CRT_ATTR_MAX_COMPACT_NAME "max compact attr" /* Max. # of attributes to store compactly */ #define H5O_CRT_ATTR_MIN_DENSE_NAME "min dense attr" /* Min. # of attributes to store densely */ #define H5O_CRT_OHDR_FLAGS_NAME "object header flags" /* Object header flags */ +#ifdef H5O_ENABLE_BOGUS +#define H5O_BOGUS_MSG_FLAGS_NAME "bogus msg flags" /* Flags for 'bogus' message */ +#define H5O_BOGUS_MSG_FLAGS_SIZE sizeof(uint8_t) +#endif /* H5O_ENABLE_BOGUS */ /* ========= Object Copy properties ============ */ #define H5O_CPY_OPTION_NAME "copy object" /* Copy options */ @@ -136,6 +141,8 @@ typedef struct H5O_copy_t { #define H5O_DRVINFO_ID 0x0014 /* Driver info message. */ #define H5O_AINFO_ID 0x0015 /* Attribute info message. */ #define H5O_REFCOUNT_ID 0x0016 /* Reference count message. */ +#define H5O_UNKNOWN_ID 0x0017 /* Placeholder message ID for unknown message. */ + /* (this should never exist in a file) */ /* Shared object message flags. @@ -432,10 +439,15 @@ typedef struct H5O_ainfo_t { /* * Reference Count Message. - * (Contains # of links to object, if >1) * (Data structure in memory) */ -typedef uint32_t H5O_refcount_t; +typedef uint32_t H5O_refcount_t; /* Contains # of links to object, if >1 */ + +/* + * "Unknown" Message. + * (Data structure in memory) + */ +typedef unsigned H5O_unknown_t; /* Original message type ID */ /* Typedef for iteration operations */ @@ -465,8 +477,7 @@ H5_DLL herr_t H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id); H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, hbool_t force); #ifdef H5O_ENABLE_BOGUS -H5_DLL herr_t H5O_bogus(H5O_loc_t *loc, hid_t dxpl_id); -H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh); +H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, unsigned mesg_flags); #endif /* H5O_ENABLE_BOGUS */ H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id); diff --git a/src/H5Otest.c b/src/H5Otest.c index 41c79ef..359c312 100644 --- a/src/H5Otest.c +++ b/src/H5Otest.c @@ -16,7 +16,7 @@ /* Programmer: Quincey Koziol * Monday, December 4, 2006 * - * Purpose: Attribute testing functions. + * Purpose: Object header testing functions. */ /****************/ @@ -357,3 +357,66 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5O_attr_dense_info_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5O_check_msg_marked_test + PURPOSE + Check if an unknown message with the "mark if unknown" flag actually gets + marked. + USAGE + herr_t H5O_check_msg_marked_test(oid, flag_val) + hid_t oid; IN: Object to check + hbool_t flag_val; IN: Desired flag value + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Locates the "unknown" message and checks that the "was unknown" flag is set + correctly. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val) +{ + H5O_t *oh = NULL; /* Object header */ + H5O_loc_t *oloc; /* Pointer to object's location */ + H5O_mesg_t *idx_msg; /* Pointer to message */ + unsigned idx; /* Index of message */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_check_msg_marked_test, FAIL) + + /* Get object location for object */ + if(NULL == (oloc = H5O_get_loc(oid))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + + /* Get the object header */ + if(NULL == (oh = H5AC_protect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + + /* Locate "unknown" message */ + for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) + if(idx_msg->type->id == H5O_UNKNOWN_ID) { + /* Check for "unknown" message having the correct flags */ + if(((idx_msg->flags & H5O_MSG_FLAG_WAS_UNKNOWN) > 0) != flag_val) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "'unknown' message has incorrect 'was unknown' flag value") + + /* Break out of loop, to indicate that the "unknown" message was found */ + break; + } /* end if */ + + /* Check for not finding an "unknown" message */ + if(idx == oh->nmesgs) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "'unknown' message type not found") + +done: + if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_check_msg_marked_test() */ + diff --git a/src/H5Ounknown.c b/src/H5Ounknown.c new file mode 100644 index 0000000..cd805a9 --- /dev/null +++ b/src/H5Ounknown.c @@ -0,0 +1,89 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ounknown.c + * Apr 19 2007 + * Quincey Koziol + * + * Purpose: Handle unknown message classes in a minimal way. + * + *------------------------------------------------------------------------- + */ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Opkg.h" /* Object headers */ + + +/* PRIVATE PROTOTYPES */ +static herr_t H5O_unknown_free(void *_mesg); + +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_UNKNOWN[1] = {{ + H5O_UNKNOWN_ID, /*message id number */ + "unknown", /*message name for debugging */ + 0, /*native message size */ + FALSE, /* messages are sharable? */ + NULL, /*decode message */ + NULL, /*encode message */ + NULL, /*copy the native value */ + NULL, /*size of symbol table entry */ + NULL, /*default reset method */ + H5O_unknown_free, /* free method */ + NULL, /* file delete method */ + NULL, /* link method */ + NULL, /*set share method */ + NULL, /*can share method */ + NULL, /* pre copy native value to file */ + NULL, /* copy native value to file */ + NULL, /* post copy native value to file */ + NULL, /* get creation index */ + NULL, /* set creation index */ + NULL /*debug the message */ +}}; + +/* Declare a free list to manage the H5O_unknown_t struct */ +H5FL_DEFINE_STATIC(H5O_unknown_t); + + +/*------------------------------------------------------------------------- + * Function: H5O_unknown_free + * + * Purpose: Free's the message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, May 1, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_unknown_free(void *mesg) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_unknown_free) + + HDassert(mesg); + + H5FL_FREE(H5O_unknown_t, mesg); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_unknown_free() */ + diff --git a/src/Makefile.am b/src/Makefile.am index b658771..40974e8 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,7 +70,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ H5Osdspace.c H5Oshared.c H5Ostab.c \ - H5Oshmesg.c H5Otest.c \ + H5Oshmesg.c H5Otest.c H5Ounknown.c \ H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ H5Pgcpl.c \ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ diff --git a/src/Makefile.in b/src/Makefile.in index a3c6817..6210d21 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -104,7 +104,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ - H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5P.lo \ + H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo \ H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \ H5Pfmpl.lo H5Pgcpl.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5R.lo H5RC.lo H5RS.lo \ @@ -420,7 +420,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ H5Osdspace.c H5Oshared.c H5Ostab.c \ - H5Oshmesg.c H5Otest.c \ + H5Oshmesg.c H5Otest.c H5Ounknown.c \ H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ H5Pgcpl.c \ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ @@ -697,6 +697,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oshmesg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ostab.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Otest.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ounknown.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5P.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pacpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdcpl.Plo@am__quote@ diff --git a/test/Makefile.am b/test/Makefile.am index d32d856..2def39a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -59,7 +59,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat testmeta # --enable-build-all at configure time. # The gen_old_* files can only be compiled with older versions of the library # so do not appear in this list. -BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \ +BUILD_ALL_PROGS=gen_bogus gen_deflate gen_filters gen_new_array gen_new_fill \ gen_new_group gen_new_mtime gen_new_super gen_noencoder \ gen_nullspace space_overflow gen_cross gen_udlinks diff --git a/test/Makefile.in b/test/Makefile.in index 47eb02c..806bea7 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -81,7 +81,7 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \ getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \ dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \ btree2$(EXEEXT) fheap$(EXEEXT) -am__EXEEXT_2 = gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \ +am__EXEEXT_2 = gen_bogus$(EXEEXT) gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \ gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \ gen_new_group$(EXEEXT) gen_new_mtime$(EXEEXT) \ gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \ @@ -172,6 +172,10 @@ flush2_SOURCES = flush2.c flush2_OBJECTS = flush2.$(OBJEXT) flush2_LDADD = $(LDADD) flush2_DEPENDENCIES = libh5test.la $(LIBHDF5) +gen_bogus_SOURCES = gen_bogus.c +gen_bogus_OBJECTS = gen_bogus.$(OBJEXT) +gen_bogus_LDADD = $(LDADD) +gen_bogus_DEPENDENCIES = libh5test.la $(LIBHDF5) gen_cross_SOURCES = gen_cross.c gen_cross_OBJECTS = gen_cross.$(OBJEXT) gen_cross_LDADD = $(LDADD) @@ -330,7 +334,7 @@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \ cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \ dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \ error_test.c extend.c external.c fheap.c fillval.c flush1.c \ - flush2.c gen_cross.c gen_deflate.c gen_filters.c \ + flush2.c gen_bogus.c gen_cross.c gen_deflate.c gen_filters.c \ gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \ getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \ @@ -342,7 +346,7 @@ DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c \ cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \ dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \ error_test.c extend.c external.c fheap.c fillval.c flush1.c \ - flush2.c gen_cross.c gen_deflate.c gen_filters.c \ + flush2.c gen_bogus.c gen_cross.c gen_deflate.c gen_filters.c \ gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \ getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \ @@ -627,7 +631,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \ # --enable-build-all at configure time. # The gen_old_* files can only be compiled with older versions of the library # so do not appear in this list. -BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \ +BUILD_ALL_PROGS = gen_bogus gen_deflate gen_filters gen_new_array gen_new_fill \ gen_new_group gen_new_mtime gen_new_super gen_noencoder \ gen_nullspace space_overflow gen_cross gen_udlinks @@ -789,6 +793,9 @@ flush1$(EXEEXT): $(flush1_OBJECTS) $(flush1_DEPENDENCIES) flush2$(EXEEXT): $(flush2_OBJECTS) $(flush2_DEPENDENCIES) @rm -f flush2$(EXEEXT) $(LINK) $(flush2_OBJECTS) $(flush2_LDADD) $(LIBS) +gen_bogus$(EXEEXT): $(gen_bogus_OBJECTS) $(gen_bogus_DEPENDENCIES) + @rm -f gen_bogus$(EXEEXT) + $(LINK) $(gen_bogus_OBJECTS) $(gen_bogus_LDADD) $(LIBS) gen_cross$(EXEEXT): $(gen_cross_OBJECTS) $(gen_cross_DEPENDENCIES) @rm -f gen_cross$(EXEEXT) $(LINK) $(gen_cross_OBJECTS) $(gen_cross_LDADD) $(LIBS) @@ -917,6 +924,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillval.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bogus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_cross.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_deflate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_filters.Po@am__quote@ diff --git a/test/gen_bogus.c b/test/gen_bogus.c new file mode 100644 index 0000000..6078e71 --- /dev/null +++ b/test/gen_bogus.c @@ -0,0 +1,100 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Quincey Koziol + * Apr 17, 2007 + * + * Purpose: This program is run to generate an HDF5 data file with several + * datasets that have "bogus" messages in their object header. + */ + +#include "hdf5.h" +#include "H5Oprivate.h" + +#define FILENAME "tbogus.h5" + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef FALSE +#define FALSE 0 +#endif /* FALSE */ + +int main(void) +{ +#ifdef H5O_ENABLE_BOGUS + hid_t fid = -1; /* File ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* Dataset creation property list ID */ + hid_t did = -1; /* Dataset ID */ + uint8_t bogus_flags = 0; /* Flags for bogus message */ + + /* Create file for test datasets */ + if((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; + + /* Create dataspace for datasets */ + if((sid = H5Screate(H5S_SCALAR)) < 0) goto error; + + /* Create dataset creation property list */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error; + + /* Add property for bogus message flags */ + if(H5Pinsert(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, H5O_BOGUS_MSG_FLAGS_SIZE, &bogus_flags, NULL, NULL, NULL, NULL, NULL, NULL) < 0) goto error; + + /* Create dataset with "bogus" message, but no message flags */ + if((did = H5Dcreate(fid, "/Dataset1", H5T_NATIVE_INT, sid, dcpl)) < 0) goto error; + if(H5Dclose(did) < 0) goto error; + + /* Set "fail if unknown" message flag for bogus message */ + bogus_flags = H5O_MSG_FLAG_FAIL_IF_UNKNOWN; + if(H5Pset(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, &bogus_flags) < 0) goto error; + + /* Create second dataset, with "fail if unknown" message flag */ + if((did = H5Dcreate(fid, "/Dataset2", H5T_NATIVE_INT, sid, dcpl)) < 0) goto error; + if(H5Dclose(did) < 0) goto error; + + /* Set "mark if unknown" message flag for bogus message */ + bogus_flags = H5O_MSG_FLAG_MARK_IF_UNKNOWN; + if(H5Pset(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, &bogus_flags) < 0) goto error; + + /* Create second dataset, with "mark if unknown" message flag */ + if((did = H5Dcreate(fid, "/Dataset3", H5T_NATIVE_INT, sid, dcpl)) < 0) goto error; + if(H5Dclose(did) < 0) goto error; + + /* Close dataset creation property list */ + if(H5Pclose(dcpl) < 0) goto error; + + /* Close dataspace */ + if(H5Sclose(sid) < 0) goto error; + + /* Close file */ + if(H5Fclose(fid) < 0) goto error; + + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Pclose(dcpl); + H5Fclose(fid); + } H5E_END_TRY; +#else /* H5O_ENABLE_BOGUS */ + HDputs("H5O_ENABLE_BOGUS compiler macro not defined!"); +#endif /* H5O_ENABLE_BOGUS */ + return 1; +} + diff --git a/test/ohdr.c b/test/ohdr.c index 43cc78e..73ede43 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -20,8 +20,10 @@ #include "H5Iprivate.h" /* * This file needs to access private datatypes from the H5O package. + * This file also needs to access the object header testing code. */ #define H5O_PACKAGE +#define H5O_TESTING #include "H5Opkg.h" /* @@ -37,7 +39,8 @@ const char *FILENAME[] = { /* The tbogus.h5 is generated from gen_bogus.c in HDF5 'test' directory. * To get this data file, define H5O_ENABLE_BOGUS in src/H5Oprivate, rebuild - * the library and simply compile gen_bogus.c with that HDF5 library and run it. */ + * the library and simply compile gen_bogus.c with that HDF5 library and run it. + */ #define FILE_BOGUS "tbogus.h5" @@ -73,12 +76,9 @@ main(void) h5_reset(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) - goto error; - if (NULL==(f=H5I_object(file))) { - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if(NULL == (f = H5I_object(file))) FAIL_STACK_ERROR + /* * Test object header creation @@ -86,65 +86,38 @@ main(void) */ TESTING("object header creation"); HDmemset(&oh_loc, 0, sizeof(oh_loc)); - if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } + if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0) + FAIL_STACK_ERROR PASSED(); + /* create a new message */ TESTING("message creation"); time_new = 11111111; - if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (ro!=time_new) { - H5_FAILED(); - HDfprintf(stdout, " got: {%ld}\n", (long)ro); - HDfprintf(stdout, " ans: {%ld}\n", (long)time_new); - goto error; - } + if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + FAIL_STACK_ERROR + if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) + FAIL_STACK_ERROR + if(ro != time_new) + TEST_ERROR PASSED(); + /* * Test modification of an existing message. */ TESTING("message modification"); time_new = 33333333; - if (H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (ro!=time_new) { - H5_FAILED(); - HDfprintf(stdout, " got: {%ld}\n", (long)ro); - HDfprintf(stdout, " ans: {%ld}\n", (long)time_new); - goto error; - } + if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + FAIL_STACK_ERROR + if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) + FAIL_STACK_ERROR + if(ro != time_new) + TEST_ERROR PASSED(); @@ -157,123 +130,187 @@ main(void) * message from an object header currently - QAK - 10/8/03) */ TESTING("object header overflow in memory"); - for (i=0; i<40; i++) { - time_new = (i+1)*1000+1; - if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } + for(i = 0; i < 40; i++) { + time_new = (i + 1) * 1000 + 1; + if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + } /* end for */ + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + FAIL_STACK_ERROR PASSED(); + /* * Test creation of a bunch of messages one after another to see * what happens when the object header overflows on disk. */ TESTING("object header overflow on disk"); - for (i=0; i<10; i++) { + for(i = 0; i < 10; i++) { time_new = (i + 1) * 1000 + 10; - if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - } + if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + FAIL_STACK_ERROR + } /* end for */ PASSED(); + /* * Delete all time messages. */ TESTING("message deletion"); - if (H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (H5O_msg_remove(&oh_loc, H5O_MTIME_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if(H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) { - H5_FAILED(); - puts(" H5O_msg_read() should have failed but didn't"); - H5Eclear2(H5E_DEFAULT); - goto error; - } - if(H5O_msg_read(&oh_loc, H5O_MTIME_ID, &ro, H5P_DATASET_XFER_DEFAULT)) { - H5_FAILED(); - puts(" H5O_msg_read() should have failed but didn't"); - H5Eclear2(H5E_DEFAULT); - goto error; - } + if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5O_msg_remove(&oh_loc, H5O_MTIME_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) + FAIL_STACK_ERROR + if(H5O_msg_read(&oh_loc, H5O_MTIME_ID, &ro, H5P_DATASET_XFER_DEFAULT)) + FAIL_STACK_ERROR PASSED(); /* release resources */ TESTING("object header closing"); - if (H5O_close(&oh_loc)<0) { - H5_FAILED(); - H5Eprint2(H5E_DEFAULT, stdout); - goto error; - } - if (H5Fclose(file)<0) goto error; + if(H5O_close(&oh_loc) < 0) + FAIL_STACK_ERROR PASSED(); - /* Test reading dataset with undefined object header message */ - TESTING("reading object with unknown header message"); + + /* Test reading datasets with undefined object header messages */ + puts("Reading objects with unknown header messages"); envval = HDgetenv("HDF5_DRIVER"); - if (envval == NULL) + if(envval == NULL) envval = "nomatch"; - if (HDstrcmp(envval, "core") && HDstrcmp(envval, "multi") && HDstrcmp(envval, "split") && HDstrcmp(envval, "family")) { - { - char testfile[512]=""; - char *srcdir = getenv("srcdir"); - - /* Build path to test file */ - if (srcdir && ((HDstrlen(srcdir) + HDstrlen(FILE_BOGUS) + 1) < sizeof(testfile))){ - HDstrcpy(testfile, srcdir); - HDstrcat(testfile, "/"); - } - HDstrcat(testfile, FILE_BOGUS); - - if ((file=H5Fopen(testfile, H5F_ACC_RDONLY, fapl))<0) - goto error; - - /* Open the dataset with the unknown header message (generated with gen_bogus.c) */ - if((dset=H5Dopen(file,"/Dataset1"))<0) - goto error; - if (H5Dclose(dset)<0) goto error; - - if (H5Fclose(file)<0) goto error; - } - PASSED(); - } - else - { + if(HDstrcmp(envval, "core") && HDstrcmp(envval, "multi") && HDstrcmp(envval, "split") && HDstrcmp(envval, "family")) { + hid_t file2; /* File ID for 'bogus' object file */ + char testpath[512] = ""; + char testfile[512] = ""; + char *srcdir = HDgetenv("srcdir"); + + /* Build path to all test files */ + if(srcdir && ((HDstrlen(srcdir) + 2) < sizeof(testpath))) { + HDstrcpy(testpath, srcdir); + HDstrcat(testpath, "/"); + } /* end if */ + + /* Build path to test file */ + if(srcdir && ((HDstrlen(testpath) + HDstrlen(FILE_BOGUS) + 1) < sizeof(testfile))) + HDstrcpy(testfile, testpath); + HDstrcat(testfile, FILE_BOGUS); + + TESTING("object with unknown header message and no flags set"); + + /* Open the file with objects that have unknown header messages (generated with gen_bogus.c) */ + if((file2 = H5Fopen(testfile, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + + /* Open the dataset with the unknown header message, but no extra flags */ + if((dset = H5Dopen(file2, "/Dataset1")) < 0) + TEST_ERROR + if(H5Dclose(dset) < 0) + TEST_ERROR + + PASSED(); + + TESTING("object with unknown header message & 'fail if unknown' flag set"); + + /* Attempt to open the dataset with the unknown header message, and "fail if unknown" flag */ + H5E_BEGIN_TRY { + dset = H5Dopen(file2, "/Dataset2"); + } H5E_END_TRY; + if(dset >= 0) { + H5Dclose(dset); + TEST_ERROR + } /* end if */ + + PASSED(); + + TESTING("object with unknown header message & 'mark if unknown' flag set"); + + /* Copy object with "mark if unknown" flag on message into file that can be modified */ + if(H5Ocopy(file2, "/Dataset3", file, "/Dataset3", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close the file we created (to flush changes to file) */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* Re-open the file created, with read-only permissions */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + + /* Open the dataset with the "mark if unknown" message */ + if((dset = H5Dopen(file, "/Dataset3")) < 0) + TEST_ERROR + + /* Check that the "unknown" message was _NOT_ marked */ + if(H5O_check_msg_marked_test(dset, FALSE) < 0) + FAIL_STACK_ERROR + + /* Close the dataset */ + if(H5Dclose(dset) < 0) + TEST_ERROR + + /* Close the file we created (to flush change to object header) */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* Re-open the file created */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Open the dataset with the "mark if unknown" message */ + if((dset = H5Dopen(file, "/Dataset3")) < 0) + TEST_ERROR + if(H5Dclose(dset) < 0) + TEST_ERROR + + /* Close the file we created (to flush change to object header) */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* Re-open the file created */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + + /* Re-open the dataset with the "mark if unknown" message */ + if((dset = H5Dopen(file, "/Dataset3")) < 0) + TEST_ERROR + + /* Check that the "unknown" message was marked */ + if(H5O_check_msg_marked_test(dset, TRUE) < 0) + FAIL_STACK_ERROR + + /* Close the dataset */ + if(H5Dclose(dset) < 0) + TEST_ERROR + + + /* Close the file with the bogus objects */ + if(H5Fclose(file2) < 0) + TEST_ERROR + + PASSED(); + } /* end if */ + else { SKIPPED(); puts(" Test not compatible with current Virtual File Driver"); - } + } /* end else */ + + /* Close the file we created */ + if(H5Fclose(file) < 0) + TEST_ERROR puts("All object header tests passed."); h5_cleanup(FILENAME, fapl); - return 0; + return(0); + +error: + puts("*** TESTS FAILED ***"); + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* end main() */ - error: - puts("*** TESTS FAILED ***"); - H5E_BEGIN_TRY { - H5Fclose(file); - } H5E_END_TRY; - return 1; -} diff --git a/test/tbogus.h5 b/test/tbogus.h5 index ddc3b65..2b8b1dd 100644 Binary files a/test/tbogus.h5 and b/test/tbogus.h5 differ -- cgit v0.12