summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c1068
1 files changed, 496 insertions, 572 deletions
diff --git a/src/H5O.c b/src/H5O.c
index 0f2ae87..b047bdd 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -26,9 +26,6 @@
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
-/* Interface initialization */
-#define H5_INTERFACE_INIT_FUNC H5O_init_interface
-
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Datasets */
@@ -47,20 +44,20 @@
/* 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) \
+#define LOAD_NATIVE(F, DXPL, MSG, ERR) \
if(NULL == (MSG)->native) { \
- const H5O_class_t *decode_type; \
+ const H5O_msg_class_t *decode_type; \
\
/* Check for shared message */ \
if ((MSG)->flags & H5O_FLAG_SHARED) \
- decode_type = H5O_SHARED; \
+ decode_type = H5O_MSG_SHARED; \
else \
decode_type = (MSG)->type; \
\
/* Decode the message */ \
HDassert(decode_type->decode); \
if(NULL == ((MSG)->native = (decode_type->decode)((F), (DXPL), (MSG)->raw))) \
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") \
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message") \
} /* end if */
/* Private typedefs */
@@ -87,7 +84,7 @@ typedef herr_t (*H5O_operator_int_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx,
*/
typedef struct H5O_typeinfo_t {
H5G_obj_t type; /*one of the public H5G_* types */
- htri_t (*isa)(H5O_loc_t*, hid_t); /*function to determine type */
+ htri_t (*isa)(H5O_t*); /*function to determine type */
char *desc; /*description of object type */
} H5O_typeinfo_t;
@@ -101,31 +98,43 @@ typedef struct H5O_addr_map_t {
/* Package variables */
-/* ID to type mapping */
-const H5O_class_t *const message_type_g[] = {
- H5O_NULL, /*0x0000 Null */
- H5O_SDSPACE, /*0x0001 Simple Dimensionality */
- H5O_LINFO, /*0x0002 Link information */
- H5O_DTYPE, /*0x0003 Data Type */
- H5O_FILL, /*0x0004 Old data storage -- fill value */
- H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */
- H5O_LINK, /*0x0006 Link */
- H5O_EFL, /*0x0007 Data storage -- external data files */
- H5O_LAYOUT, /*0x0008 Data Layout */
+/* Header message ID to class mapping */
+const H5O_msg_class_t *const H5O_msg_class_g[] = {
+ H5O_MSG_NULL, /*0x0000 Null */
+ H5O_MSG_SDSPACE, /*0x0001 Simple Dimensionality */
+ H5O_MSG_LINFO, /*0x0002 Link information */
+ H5O_MSG_DTYPE, /*0x0003 Data Type */
+ H5O_MSG_FILL, /*0x0004 Old data storage -- fill value */
+ H5O_MSG_FILL_NEW, /*0x0005 New Data storage -- fill value */
+ H5O_MSG_LINK, /*0x0006 Link */
+ H5O_MSG_EFL, /*0x0007 Data storage -- external data files */
+ H5O_MSG_LAYOUT, /*0x0008 Data Layout */
#ifdef H5O_ENABLE_BOGUS
- H5O_BOGUS, /*0x0009 "Bogus" */
+ H5O_MSG_BOGUS, /*0x0009 "Bogus" */
#else /* H5O_ENABLE_BOGUS */
- NULL, /*0x0009 "Bogus" */
+ NULL, /*0x0009 "Bogus" */
#endif /* H5O_ENABLE_BOGUS */
- H5O_GINFO, /*0x000A Group Information */
- H5O_PLINE, /*0x000B Data storage -- filter pipeline */
- H5O_ATTR, /*0x000C Attribute list */
- H5O_NAME, /*0x000D Object name */
- H5O_MTIME, /*0x000E Object modification date and time */
- H5O_SHARED, /*0x000F Shared header message */
- H5O_CONT, /*0x0010 Object header continuation */
- H5O_STAB, /*0x0011 Symbol table */
- H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
+ H5O_MSG_GINFO, /*0x000A Group Information */
+ H5O_MSG_PLINE, /*0x000B Data storage -- filter pipeline */
+ H5O_MSG_ATTR, /*0x000C Attribute list */
+ H5O_MSG_NAME, /*0x000D Object name */
+ H5O_MSG_MTIME, /*0x000E Object modification date and time */
+ H5O_MSG_SHARED, /*0x000F Shared header message */
+ H5O_MSG_CONT, /*0x0010 Object header continuation */
+ H5O_MSG_STAB, /*0x0011 Symbol table */
+ H5O_MSG_MTIME_NEW, /*0x0012 New Object modification date and time */
+};
+
+/* Header object ID to class mapping */
+/*
+ * Initialize the object class info table. Begin with the most general types
+ * and end with the most specific. For instance, any object that has a
+ * datatype message is a datatype but only some of them are datasets.
+ */
+const H5O_obj_class_t *const H5O_obj_class_g[] = {
+ H5O_OBJ_DATATYPE, /* Datatype object (H5G_TYPE - 2) */
+ H5O_OBJ_DATASET, /* Dataset object (H5G_DATASET - 1) */
+ H5O_OBJ_GROUP, /* Group object (H5G_GROUP - 0) */
};
/* Declare a free list to manage the H5O_t struct */
@@ -143,9 +152,6 @@ H5FL_BLK_DEFINE(chunk_image);
/* Library private variables */
/* Local variables */
-static H5O_typeinfo_t *H5O_type_g = NULL; /*object typing info */
-static size_t H5O_ntypes_g = 0; /*entries in type table */
-static size_t H5O_atypes_g = 0; /*entries allocated */
/* Declare external the free list for time_t's */
H5FL_EXTERN(time_t);
@@ -157,33 +163,30 @@ H5FL_EXTERN(H5O_cont_t);
H5FL_DEFINE_STATIC(H5O_addr_map_t);
/* PRIVATE PROTOTYPES */
-static herr_t H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t),
- const char *_desc);
static herr_t H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5O_loc_t *loc/*out*/, haddr_t header);
-static herr_t H5O_reset_real(const H5O_class_t *type, void *native);
-static void * H5O_copy_real(const H5O_class_t *type, const void *mesg,
+static herr_t H5O_reset_real(const H5O_msg_class_t *type, void *native);
+static void * H5O_copy_real(const H5O_msg_class_t *type, const void *mesg,
void *dst);
-static int H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type,
+static int H5O_count_real(H5O_loc_t *loc, const H5O_msg_class_t *type,
hid_t dxpl_id);
-static htri_t H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type,
- int sequence, hid_t dxpl_id);
#ifdef NOT_YET
-static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
+static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_msg_class_t *type, const void *mesg,
H5HG_t *hobj/*out*/);
#endif /* NOT_YET */
static unsigned H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- const H5O_class_t **type_p, int sequence);
-static int H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type,
+ const H5O_msg_class_t **type_p, int sequence);
+static int H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type,
int overwrite, unsigned flags, unsigned update_flags, const void *mesg,
hid_t dxpl_id);
static int H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- const H5O_class_t *type, unsigned flags, const void *mesg,
+ const H5O_msg_class_t *type, unsigned flags, const void *mesg,
unsigned * oh_flags_ptr);
-static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type,
+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 unsigned H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- const H5O_class_t *type, size_t size, hbool_t * oh_dirtied_ptr);
+ 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 htri_t H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
static htri_t H5O_merge_null(H5F_t *f, H5O_t *oh);
static htri_t H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
@@ -196,15 +199,17 @@ 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_class_t *orig_type, const void *orig_mesg, H5O_shared_t *sh_mesg,
- const H5O_class_t **new_type, const void **new_mesg, hid_t dxpl_id,
+ 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,
unsigned * oh_flags_ptr);
-static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
+static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_msg_class_t *type,
const void *mesg, unsigned flags, unsigned update_flags,
unsigned * oh_flags_ptr);
-static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type,
+static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type,
H5AC_protect_t prot, hbool_t internal, void *op, void *op_data, hid_t dxpl_id);
-static void * H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
+static H5G_obj_t H5O_obj_type_real(H5O_t *oh);
+static const H5O_obj_class_t *H5O_obj_class(H5O_t *oh);
+static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src,
H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list);
@@ -212,178 +217,6 @@ static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
/*-------------------------------------------------------------------------
- * Function: H5O_init
- *
- * Purpose: Initialize the interface from some other package.
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Wednesday, September 28, 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5O_init(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5O_init, FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_init() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_init_interface
- *
- * Purpose: Initialize the H5O interface.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Tuesday, January 6, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_init_interface(void)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_init_interface)
-
- /*
- * Initialize the type info table. Begin with the most general types and
- * end with the most specific. For instance, any object that has a data
- * type message is a datatype but only some of them are datasets.
- */
- H5O_register_type(H5G_TYPE, H5T_isa, "datatype");
- H5O_register_type(H5G_GROUP, H5G_isa, "group");
- H5O_register_type(H5G_DATASET, H5D_isa, "dataset");
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5O_init_interface() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_term_interface
- *
- * Purpose: Terminates the H5O interface
- *
- * Return: Success: Positive if anything is done that might
- * affect other interfaces; zero otherwise.
- *
- * Failure: Negative.
- *
- * Programmer: Quincey Koziol
- * Monday, September 19, 2005
- *
- *-------------------------------------------------------------------------
- */
-int
-H5O_term_interface(void)
-{
- int n = 0;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_term_interface)
-
- if(H5_interface_initialize_g) {
- size_t u;
-
- /* Empty the object type table */
- for(u = 0; u < H5O_ntypes_g; u++)
- H5MM_xfree(H5O_type_g[u].desc);
- H5O_ntypes_g = H5O_atypes_g = 0;
- H5O_type_g = H5MM_xfree(H5O_type_g);
-
- /* Mark closed */
- H5_interface_initialize_g = 0;
- n = 1; /*H5O*/
- } /* end if */
-
- FUNC_LEAVE_NOAPI(n)
-} /* H5O_term_interface() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_register_type
- *
- * Purpose: Register a new object type so H5O_get_type() can detect it.
- * One should always register a general type before a more
- * specific type. For instance, any object that has a datatype
- * message is a datatype, but only some of those objects are
- * datasets.
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Monday, September 19, 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t), const char *_desc)
-{
- char *desc = NULL;
- size_t i;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_register_type)
-
- HDassert(type >= 0);
- HDassert(isa);
- HDassert(_desc);
-
- /* Copy the description */
- if(NULL == (desc = H5MM_strdup(_desc)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for object type description")
-
- /*
- * If the type is already registered then just update its entry without
- * moving it to the end
- */
- for(i = 0; i < H5O_ntypes_g; i++) {
- if (H5O_type_g[i].type == type) {
- H5O_type_g[i].isa = isa;
- H5MM_xfree(H5O_type_g[i].desc);
- H5O_type_g[i].desc = desc;
- HGOTO_DONE(SUCCEED);
- } /* end if */
- } /* end for */
-
- /* Increase table size */
- if(H5O_ntypes_g >= H5O_atypes_g) {
- size_t n = MAX(32, 2 * H5O_atypes_g);
- H5O_typeinfo_t *x = H5MM_realloc(H5O_type_g, n * sizeof(H5O_typeinfo_t));
-
- if (!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for objec type table")
- H5O_atypes_g = n;
- H5O_type_g = x;
- } /* end if */
-
- /* Add a new entry */
- H5O_type_g[H5O_ntypes_g].type = type;
- H5O_type_g[H5O_ntypes_g].isa = isa;
- H5O_type_g[H5O_ntypes_g].desc = desc; /*already copied*/
- H5O_ntypes_g++;
-
-done:
- if(ret_value < 0)
- H5MM_xfree(desc);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_register_type() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_create
*
* Purpose: Creates a new object header. Allocates space for it and
@@ -495,7 +328,7 @@ H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/, haddr_
if(NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, (size_t)oh->alloc_nmesgs)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- oh->mesg[0].type = H5O_NULL;
+ oh->mesg[0].type = H5O_MSG_NULL;
oh->mesg[0].dirty = TRUE;
oh->mesg[0].native = NULL;
oh->mesg[0].raw = oh->chunk[0].image + H5O_SIZEOF_MSGHDR(f);
@@ -536,9 +369,7 @@ done:
herr_t
H5O_open(const H5O_loc_t *loc)
{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5O_open, FAIL)
+ FUNC_ENTER_NOAPI_NOFUNC(H5O_open)
/* Check args */
HDassert(loc);
@@ -552,8 +383,7 @@ H5O_open(const H5O_loc_t *loc)
/* Increment open-lock counters */
loc->file->nopen_objs++;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_open() */
@@ -635,14 +465,14 @@ done:
herr_t
H5O_reset(unsigned type_id, void *native)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_reset,FAIL);
/* check args */
- assert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert(type_id < NELMTS(H5O_msg_class_g));
+ type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Call the "real" reset routine */
@@ -667,12 +497,10 @@ done:
* matzke@llnl.gov
* Aug 12 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_reset_real(const H5O_class_t *type, void *native)
+H5O_reset_real(const H5O_msg_class_t *type, void *native)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -715,21 +543,20 @@ done:
void *
H5O_free (unsigned type_id, void *mesg)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
void * ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_free, NULL);
+ FUNC_ENTER_NOAPI_NOFUNC(H5O_free)
/* check args */
- assert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
+ 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);
/* Call the "real" free routine */
- ret_value=H5O_free_real(type, mesg);
+ ret_value = H5O_free_real(type, mesg);
-done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_free() */
@@ -755,7 +582,7 @@ H5O_free_mesg(H5O_mesg_t *mesg)
/* Free any native information */
if(mesg->flags & H5O_FLAG_SHARED)
- mesg->native = H5O_free_real(H5O_SHARED, mesg->native);
+ mesg->native = H5O_free_real(H5O_MSG_SHARED, mesg->native);
else
mesg->native = H5O_free_real(mesg->type, mesg->native);
@@ -779,7 +606,7 @@ H5O_free_mesg(H5O_mesg_t *mesg)
*-------------------------------------------------------------------------
*/
void *
-H5O_free_real(const H5O_class_t *type, void *msg_native)
+H5O_free_real(const H5O_msg_class_t *type, void *msg_native)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_real)
@@ -822,14 +649,14 @@ H5O_free_real(const H5O_class_t *type, void *msg_native)
void *
H5O_copy (unsigned type_id, const void *mesg, void *dst)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_copy, NULL);
/* check args */
- assert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert(type_id < NELMTS(H5O_msg_class_g));
+ type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Call the "real" copy routine */
@@ -859,7 +686,7 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_copy_real (const H5O_class_t *type, const void *mesg, void *dst)
+H5O_copy_real (const H5O_msg_class_t *type, const void *mesg, void *dst)
{
void *ret_value = NULL;
@@ -988,7 +815,7 @@ done:
int
H5O_count(H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_count, FAIL)
@@ -997,8 +824,8 @@ H5O_count(H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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);
/* Call the "real" count routine */
@@ -1026,7 +853,7 @@ done:
*-------------------------------------------------------------------------
*/
static int
-H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type, hid_t dxpl_id)
+H5O_count_real(H5O_loc_t *loc, const H5O_msg_class_t *type, hid_t dxpl_id)
{
H5O_t *oh = NULL;
int acc;
@@ -1082,29 +909,34 @@ done:
htri_t
H5O_exists(H5O_loc_t *loc, unsigned type_id, int sequence, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ H5O_t *oh = NULL; /* Object header for location */
htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_exists, FAIL)
HDassert(loc);
HDassert(loc->file);
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
- HDassert(type);
+ HDassert(type_id < NELMTS(H5O_msg_class_g));
HDassert(sequence >= 0);
+ /* Load the object header */
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
/* Call the "real" exists routine */
- if((ret_value = H5O_exists_real(loc, type, sequence, dxpl_id)) < 0)
+ if((ret_value = H5O_exists_oh(oh, type_id, sequence)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message")
done:
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_exists() */
/*-------------------------------------------------------------------------
- * Function: H5O_exists_real
+ * Function: H5O_exists_oh
*
* Purpose: Determines if a particular message exists in an object
* header without trying to decode the message.
@@ -1121,24 +953,21 @@ done:
*
*-------------------------------------------------------------------------
*/
-static htri_t
-H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type, int sequence, hid_t dxpl_id)
+htri_t
+H5O_exists_oh(H5O_t *oh, unsigned type_id, int sequence)
{
- H5O_t *oh = NULL;
- unsigned u;
- htri_t ret_value; /* Return value */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
+ unsigned u; /* Local index variable */
+ htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_exists_real)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_exists_oh)
- HDassert(loc);
- HDassert(loc->file);
+ HDassert(oh);
+ 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(sequence >= 0);
- /* Load the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
-
/* Scan through the messages looking for the right one */
for(u = 0; u < oh->nmesgs; u++) {
if(type->id != oh->mesg[u].type->id)
@@ -1150,12 +979,8 @@ H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type, int sequence, hid_t dxp
/* Set return value */
ret_value = (sequence < 0);
-done:
- if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
-
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_exists_real() */
+} /* end H5O_exists_oh() */
/*-------------------------------------------------------------------------
@@ -1184,7 +1009,7 @@ done:
void *
H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_read, NULL)
@@ -1193,8 +1018,8 @@ H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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(sequence >= 0);
@@ -1231,7 +1056,7 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
+H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
{
H5O_t *oh = NULL;
int idx;
@@ -1257,7 +1082,7 @@ H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, void
if(oh->mesg[idx].flags & H5O_FLAG_SHARED) {
/*
* If the message is shared then then the native pointer points to an
- * H5O_SHARED message. We use that information to look up the real
+ * H5O_MSG_SHARED message. We use that information to look up the real
* message in the global heap or some other object header.
*/
H5O_shared_t *shared;
@@ -1306,7 +1131,7 @@ done:
*-------------------------------------------------------------------------
*/
static unsigned
-H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p, int sequence)
+H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t **type_p, int sequence)
{
unsigned u;
unsigned ret_value;
@@ -1333,7 +1158,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
* Decode the message if necessary. If the message is shared then decode
* a shared message, ignoring the message type.
*/
- LOAD_NATIVE(f, dxpl_id, &(oh->mesg[u]))
+ LOAD_NATIVE(f, dxpl_id, &(oh->mesg[u]), UFAIL)
/*
* Return the message type. If this is a shared message then return the
@@ -1387,7 +1212,7 @@ int
H5O_modify(H5O_loc_t *loc, unsigned type_id, int overwrite,
unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_modify, FAIL)
@@ -1396,8 +1221,8 @@ H5O_modify(H5O_loc_t *loc, unsigned type_id, int overwrite,
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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(mesg);
HDassert(0 == (flags & ~H5O_FLAG_BITS));
@@ -1446,7 +1271,7 @@ done:
*-------------------------------------------------------------------------
*/
static int
-H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type, int overwrite,
+H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type, int overwrite,
unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id)
{
H5O_t *oh = NULL;
@@ -1618,24 +1443,13 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * field of the cache info directly.
- *
*-------------------------------------------------------------------------
*/
int
H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags,
const void *mesg, unsigned * oh_flags_ptr)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_append,FAIL);
@@ -1643,8 +1457,8 @@ H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags,
/* check args */
assert(f);
assert(oh);
- assert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert(type_id < NELMTS(H5O_msg_class_g));
+ type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
assert(type);
assert(0==(flags & ~H5O_FLAG_BITS));
assert(mesg);
@@ -1677,7 +1491,7 @@ done:
*-------------------------------------------------------------------------
*/
static int
-H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
+H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
unsigned flags, const void *mesg, unsigned * oh_flags_ptr)
{
unsigned idx; /* Index of message to modify */
@@ -1724,8 +1538,8 @@ done:
*-------------------------------------------------------------------------
*/
static unsigned
-H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
- const void *orig_mesg, H5O_shared_t *sh_mesg, const H5O_class_t **new_type,
+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, unsigned * oh_flags_ptr)
{
size_t size; /* Size of space allocated for object header */
@@ -1759,7 +1573,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
*flags &= ~H5O_FLAG_SHARED;
} else {
/* Change type & message to use shared information */
- *new_type=H5O_SHARED;
+ *new_type=H5O_MSG_SHARED;
*new_mesg=sh_mesg;
} /* end else */
} /* end if */
@@ -1795,18 +1609,10 @@ done:
* Programmer: Quincey Koziol
* Friday, September 3, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
+H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_msg_class_t *type,
const void *mesg, unsigned flags, unsigned update_flags,
unsigned * oh_flags_ptr)
{
@@ -1874,7 +1680,7 @@ H5O_touch_oh(H5F_t *f,
/* Look for existing message */
for (idx=0; idx < oh->nmesgs; idx++) {
- if (H5O_MTIME==oh->mesg[idx].type || H5O_MTIME_NEW==oh->mesg[idx].type)
+ if (H5O_MSG_MTIME==oh->mesg[idx].type || H5O_MSG_MTIME_NEW==oh->mesg[idx].type)
break;
}
@@ -1893,10 +1699,9 @@ H5O_touch_oh(H5F_t *f,
if (idx==oh->nmesgs) {
if (!force)
HGOTO_DONE(SUCCEED); /*nothing to do*/
- size = (H5O_MTIME_NEW->raw_size)(f, &now);
+ size = (H5O_MSG_MTIME_NEW->raw_size)(f, &now);
- if ((idx=H5O_alloc(f, dxpl_id, oh, H5O_MTIME_NEW,
- size, oh_flags_ptr))==UFAIL)
+ if ((idx=H5O_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, size, oh_flags_ptr))==UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message");
}
@@ -1927,12 +1732,6 @@ done:
* Programmer: Robb Matzke
* Monday, July 27, 1998
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1995,14 +1794,14 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t * oh_flags_ptr)
/* Look for existing message */
for(idx = 0; idx < oh->nmesgs; idx++)
- if(H5O_BOGUS == oh->mesg[idx].type)
+ if(H5O_MSG_BOGUS == oh->mesg[idx].type)
break;
/* Create a new message */
if(idx == oh->nmesgs) {
- size_t size = (H5O_BOGUS->raw_size)(f, NULL);
+ size_t size = (H5O_MSG_BOGUS->raw_size)(f, NULL);
- if((idx = H5O_alloc(f, dxpl_id, oh, H5O_BOGUS, size, oh_flags_ptr)) < 0)
+ if((idx = H5O_alloc(f, dxpl_id, oh, H5O_MSG_BOGUS, size, oh_flags_ptr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for 'bogus' message")
/* Allocate the native message in memory */
@@ -2104,7 +1903,7 @@ done:
herr_t
H5O_remove(H5O_loc_t *loc, unsigned type_id, int sequence, hbool_t adj_link, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_remove, FAIL)
@@ -2113,8 +1912,8 @@ H5O_remove(H5O_loc_t *loc, unsigned type_id, int sequence, hbool_t adj_link, hid
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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);
/* Call the "real" remove routine */
@@ -2147,7 +1946,7 @@ herr_t
H5O_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_remove_op, FAIL)
@@ -2156,8 +1955,8 @@ H5O_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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);
/* Call the "real" remove routine */
@@ -2227,7 +2026,7 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
H5O_free_mesg(mesg);
/* Change message type to nil and zero it */
- mesg->type = H5O_NULL;
+ mesg->type = H5O_MSG_NULL;
HDmemset(mesg->raw, 0, mesg->raw_size);
/* Indicate that the message was modified */
@@ -2268,7 +2067,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence,
+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)
{
H5O_iter_ud1_t udata; /* User data for iterator */
@@ -2308,6 +2107,53 @@ 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 (H5O_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_move_msgs_forward
*
* Purpose: Move messages toward first chunk
@@ -2330,7 +2176,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
FUNC_ENTER_NOAPI_NOINIT(H5O_move_msgs_forward)
/* check args */
- HDassert(oh != NULL);
+ HDassert(oh);
/* Loop until no messages packed */
/* (Double loop is not very efficient, but it would be some extra work to add
@@ -2364,7 +2210,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
if(H5O_NULL_ID != nonnull_msg->type->id) {
/* Make certain non-null message has been translated into native form */
/* (So that when we mark it dirty, it will get copied back into raw chunk image) */
- LOAD_NATIVE(f, dxpl_id, nonnull_msg)
+ LOAD_NATIVE(f, dxpl_id, nonnull_msg, FAIL)
/* Adjust non-null message's offset in chunk */
nonnull_msg->raw = curr_msg->raw;
@@ -2411,7 +2257,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
/* Make certain non-null message has been translated into native form */
/* (So that when we mark it dirty, it will get copied back into raw chunk image) */
- LOAD_NATIVE(f, dxpl_id, curr_msg)
+ LOAD_NATIVE(f, dxpl_id, curr_msg, FAIL)
/* Change information for non-null message */
if(curr_msg->raw_size == null_msg->raw_size) {
@@ -2449,20 +2295,15 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
/* Create new null message for previous location of non-null message */
if(oh->nmesgs >= oh->alloc_nmesgs) {
- unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
- H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
-
- if(NULL == x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- oh->alloc_nmesgs = na;
- oh->mesg = x;
+ if(H5O_alloc_msgs(oh, (size_t)0) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
} /* end if */
/* Get message # for new message */
new_null_msg = oh->nmesgs++;
/* Initialize new null message */
- oh->mesg[new_null_msg].type = H5O_NULL;
+ 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;
@@ -2661,8 +2502,8 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
if(H5O_CONT_ID == cont_msg->type->id) {
/* Decode current continuation message if necessary */
if(NULL == cont_msg->native) {
- HDassert(H5O_CONT->decode);
- cont_msg->native = (H5O_CONT->decode) (f, dxpl_id, cont_msg->raw);
+ 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 */
@@ -2692,7 +2533,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
H5O_free_mesg(cont_msg);
/* Change message type to nil and zero it */
- cont_msg->type = H5O_NULL;
+ cont_msg->type = H5O_MSG_NULL;
HDmemset(cont_msg->raw, 0, cont_msg->raw_size);
/* Indicate that the continuation message was modified */
@@ -2916,20 +2757,15 @@ H5O_alloc_extend_chunk(H5F_t *f,
else {
/* Create a new null message */
if(oh->nmesgs >= oh->alloc_nmesgs) {
- unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
- H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
-
- if(NULL == x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- oh->alloc_nmesgs = na;
- oh->mesg = x;
+ if(H5O_alloc_msgs(oh, (size_t)0) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
} /* end if */
/* Set extension message */
extend_msg = oh->nmesgs++;
/* Initialize new null message */
- oh->mesg[extend_msg].type = H5O_NULL;
+ 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 +
@@ -3128,18 +2964,8 @@ H5O_alloc_new_chunk(H5F_t *f,
* that could be generated below.
*/
if(oh->nmesgs + 3 > oh->alloc_nmesgs) {
- int old_alloc = oh->alloc_nmesgs;
- unsigned na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3);
- H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
-
- if(!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
- oh->alloc_nmesgs = na;
- oh->mesg = x;
-
- /* Set new object header info to zeros */
- HDmemset(&oh->mesg[old_alloc], 0,
- (oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
+ if(H5O_alloc_msgs(oh, (size_t)3) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
} /* end if */
/*
@@ -3147,7 +2973,7 @@ H5O_alloc_new_chunk(H5F_t *f,
*/
if(found_null < 0) {
found_null = u = oh->nmesgs++;
- oh->mesg[u].type = H5O_NULL;
+ oh->mesg[u].type = H5O_MSG_NULL;
oh->mesg[u].dirty = TRUE;
oh->mesg[u].native = NULL;
oh->mesg[u].raw = oh->mesg[found_other].raw;
@@ -3165,7 +2991,7 @@ H5O_alloc_new_chunk(H5F_t *f,
size -= H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
} /* end if */
idx = oh->nmesgs++;
- oh->mesg[idx].type = H5O_NULL;
+ 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(f);
@@ -3179,7 +3005,7 @@ H5O_alloc_new_chunk(H5F_t *f,
*/
if(oh->mesg[found_null].raw_size > cont_size) {
u = oh->nmesgs++;
- oh->mesg[u].type = H5O_NULL;
+ oh->mesg[u].type = H5O_MSG_NULL;
oh->mesg[u].dirty = TRUE;
oh->mesg[u].native = NULL;
oh->mesg[u].raw = oh->mesg[found_null].raw +
@@ -3196,7 +3022,7 @@ H5O_alloc_new_chunk(H5F_t *f,
/*
* Initialize the continuation message.
*/
- oh->mesg[found_null].type = H5O_CONT;
+ oh->mesg[found_null].type = H5O_MSG_CONT;
oh->mesg[found_null].dirty = TRUE;
if (NULL==(cont = H5FL_MALLOC(H5O_cont_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
@@ -3232,7 +3058,7 @@ static unsigned
H5O_alloc(H5F_t *f,
hid_t dxpl_id,
H5O_t *oh,
- const H5O_class_t *type,
+ const H5O_msg_class_t *type,
size_t size,
unsigned * oh_flags_ptr)
{
@@ -3309,24 +3135,14 @@ H5O_alloc(H5F_t *f,
/* Check if we need to extend message table */
if(oh->nmesgs >= oh->alloc_nmesgs) {
- int old_alloc = oh->alloc_nmesgs;
- unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
- H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
-
- if(!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
- oh->alloc_nmesgs = na;
- oh->mesg = x;
-
- /* Set new object header info to zeros */
- HDmemset(&oh->mesg[old_alloc], 0,
- (oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
+ if(H5O_alloc_msgs(oh, (size_t)0) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
/* "Retarget" local 'msg' pointer into newly allocated array of messages */
msg = &oh->mesg[idx];
} /* end if */
null_msg = &(oh->mesg[oh->nmesgs++]);
- null_msg->type = H5O_NULL;
+ null_msg->type = H5O_MSG_NULL;
null_msg->dirty = TRUE;
null_msg->native = NULL;
null_msg->raw = msg->raw + mesg_size;
@@ -3369,7 +3185,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
+H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_msg_class_t *type, const void *mesg,
H5HG_t *hobj/*out*/)
{
size_t size;
@@ -3420,14 +3236,14 @@ done:
size_t
H5O_raw_size(unsigned type_id, const H5F_t *f, const void *mesg)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_raw_size,0)
/* Check args */
- HDassert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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->raw_size);
HDassert(f);
@@ -3459,14 +3275,14 @@ done:
size_t
H5O_mesg_size(unsigned type_id, const H5F_t *f, const void *mesg)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_mesg_size,0)
/* Check args */
- HDassert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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->raw_size);
HDassert(f);
@@ -3509,14 +3325,14 @@ done:
herr_t
H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_get_share,FAIL)
/* Check args */
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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->get_share);
HDassert(f);
@@ -3642,7 +3458,7 @@ done:
static herr_t
H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
{
- const H5O_class_t *type; /* Type of object to free */
+ 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)
@@ -3653,7 +3469,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_SHARED;
+ type = H5O_MSG_SHARED;
else
type = mesg->type;
@@ -3758,14 +3574,14 @@ done:
herr_t
H5O_encode(H5F_t *f, unsigned char *buf, void *obj, unsigned type_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_encode,FAIL);
/* check args */
- assert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert(type_id < NELMTS(H5O_msg_class_g));
+ type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Encode */
@@ -3798,14 +3614,14 @@ done:
void*
H5O_decode(H5F_t *f, const unsigned char *buf, unsigned type_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
void *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI(H5O_decode,NULL);
/* check args */
- assert(type_id < NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert(type_id < NELMTS(H5O_msg_class_g));
+ type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* decode */
@@ -3846,19 +3662,13 @@ done:
* C. Negative causes the iterator to immediately return that value,
* indicating failure.
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
herr_t
H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op,
void *op_data, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_iterate, FAIL)
@@ -3867,8 +3677,8 @@ H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op,
HDassert(loc);
HDassert(loc->file);
HDassert(H5F_addr_defined(loc->addr));
- HDassert(type_id < NELMTS(message_type_g));
- type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ 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);
/* Call the "real" iterate routine */
@@ -3914,7 +3724,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, H5AC_protect_t prot,
+H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect_t prot,
hbool_t internal, void *op, void *op_data, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Pointer to actual object header */
@@ -3944,7 +3754,7 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, H5AC_protect_t p
* Decode the message if necessary. If the message is shared then decode
* a shared message, ignoring the message type.
*/
- LOAD_NATIVE(loc->file, dxpl_id, idx_msg)
+ LOAD_NATIVE(loc->file, dxpl_id, idx_msg, FAIL)
/* Check for making an "internal" (i.e. within the H5O package) callback */
if(internal) {
@@ -4005,20 +3815,62 @@ done:
H5G_obj_t
H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id)
{
- size_t i; /* Local index variable */
+ H5O_t *oh = NULL; /* Object header for location */
H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */
FUNC_ENTER_NOAPI(H5O_obj_type, H5G_UNKNOWN)
+ /* Load the object header */
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, H5G_UNKNOWN, "unable to load object header")
+
+ /* Test whether entry qualifies as a particular type of object */
+ if((ret_value = H5O_obj_type_real(oh)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
+
+done:
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, H5G_UNKNOWN, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_obj_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_obj_type_real
+ *
+ * Purpose: Returns the type of object pointed to by `oh'.
+ *
+ * Note: Same algorithm as H5O_obj_class()
+ *
+ * Return: Success: An object type defined in H5Gpublic.h
+ * Failure: H5G_UNKNOWN
+ *
+ * Programmer: Quincey Koziol
+ * Monday, November 21, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5G_obj_t
+H5O_obj_type_real(H5O_t *oh)
+{
+ size_t i; /* Local index variable */
+ H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_obj_type_real)
+
+ /* Sanity check */
+ HDassert(oh);
+
/* Test whether entry qualifies as a particular type of object */
/* (Note: loop is in reverse order, to test specific objects first) */
- for(i = H5O_ntypes_g; i > 0; --i) {
+ for(i = NELMTS(H5O_obj_class_g); i > 0; --i) {
htri_t isa; /* Is entry a particular type? */
- if((isa = (H5O_type_g[i-1].isa)(loc, dxpl_id)) < 0)
+ if((isa = (H5O_obj_class_g[i - 1]->isa)(oh)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
else if(isa)
- HGOTO_DONE(H5O_type_g[i-1].type)
+ HGOTO_DONE(H5O_obj_class_g[i - 1]->type)
} /* end for */
if(0 == i)
@@ -4026,7 +3878,52 @@ H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_obj_type() */
+} /* end H5O_obj_type_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_obj_class
+ *
+ * Purpose: Returns the class of object pointed to by `oh'.
+ *
+ * Note: Same algorithm as H5O_obj_type_real()
+ *
+ * Return: Success: An object class
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, November 21, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5O_obj_class_t *
+H5O_obj_class(H5O_t *oh)
+{
+ size_t i; /* Local index variable */
+ const H5O_obj_class_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class)
+
+ /* Sanity check */
+ HDassert(oh);
+
+ /* Test whether entry qualifies as a particular type of object */
+ /* (Note: loop is in reverse order, to test specific objects first) */
+ for(i = NELMTS(H5O_obj_class_g); i > 0; --i) {
+ htri_t isa; /* Is entry a particular type? */
+
+ if((isa = (H5O_obj_class_g[i - 1]->isa)(oh)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to determine object type")
+ else if(isa)
+ HGOTO_DONE(H5O_obj_class_g[i - 1])
+ } /* end for */
+
+ if(0 == i)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to determine object type")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_obj_class() */
/*-------------------------------------------------------------------------
@@ -4122,7 +4019,7 @@ H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth)
*-------------------------------------------------------------------------
*/
static void *
-H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
+H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *native_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata)
{
void *ret_value;
@@ -4162,16 +4059,16 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src,
H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
- uint8_t buf[16], *p;
H5O_t *oh_src = NULL; /* Object header for source object */
H5O_t *oh_dst = NULL; /* Object header for destination object */
unsigned chunkno = 0, mesgno = 0;
- size_t chunk_size, hdr_size;
+ size_t hdr_size;
haddr_t addr_new;
H5O_mesg_t *mesg_src; /* Message in source object header */
H5O_mesg_t *mesg_dst; /* Message in source object header */
- H5O_chunk_t *chunk = NULL;
- unsigned dst_oh_flags = H5AC__NO_FLAGS_SET; /* used to indicate whether destination header was modified */
+ const H5O_msg_class_t *copy_type; /* Type of message to use for copying */
+ const H5O_obj_class_t *obj_class; /* Type of object we are copying */
+ void *udata = NULL; /* User data for passing to message callbacks */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real)
@@ -4182,148 +4079,180 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src,
HDassert(oloc_dst->file);
HDassert(map_list);
+ /* Get source object header */
if(NULL == (oh_src = H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
- /* get the size of the file header of the destination file */
- hdr_size = H5O_SIZEOF_HDR(oloc_dst->file);
-
- /* allocate memory space for the destitnation chunks */
- if(NULL == (chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh_src->nchunks)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Allocate space for the first chunk */
- if(HADDR_UNDEF == (addr_new = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + oh_src->chunk[0].size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
-
- /* Return the first chunk address */
- oloc_dst->addr = addr_new;
+ /* Get pointer to object class for this object */
+ if(NULL == (obj_class = H5O_obj_class(oh_src)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
- /* Set chunk's address */
- chunk[0].addr = addr_new + (hsize_t)hdr_size;
+ /* Retrieve user data for particular type of object to copy */
+ if(obj_class->get_copy_file_udata &&
+ (NULL == (udata = (obj_class->get_copy_file_udata)())))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to retrieve copy user data")
- /* Encode header information */
- p = buf;
+ /* Flush any dirty messages in source object header to update the header chunks */
+ if(H5O_flush_msgs(oloc_src->file, oh_src) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object header messages")
- /* encode version */
- *p++ = H5O_VERSION;
+ /* get the size of the file header of the destination file */
+ hdr_size = H5O_SIZEOF_HDR(oloc_dst->file);
- /* reserved */
- *p++ = 0;
- /* encode number of messages */
- UINT16ENCODE(p, oh_src->nmesgs);
+ /* Allocate the destination object header and fill in header fields */
+ if(NULL == (oh_dst = H5FL_MALLOC(H5O_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- /* encode link count (at zero initially) */
- UINT32ENCODE(p, 0);
+ /* Initialize header information */
+ oh_dst->version = H5O_VERSION;
+ oh_dst->nlink = 0;
- /* encode body size */
- UINT32ENCODE(p, oh_src->chunk[0].size);
+ /* Initialize size of chunk array */
+ oh_dst->alloc_nchunks = oh_dst->nchunks = oh_src->nchunks;
- /* zero to alignment */
- HDmemset(p, 0, (size_t)(hdr_size-12));
+ /* Allocate memory for the chunk array */
+ if(NULL == (oh_dst->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, oh_dst->alloc_nchunks)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* need to allocate all the chunks for the destination before copy the chunk message
because continuation chunk message will need to know the chunk address of address of
continuation block.
*/
- for(chunkno = 1; chunkno < oh_src->nchunks; chunkno++) {
- if(HADDR_UNDEF == (chunk[chunkno].addr = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh_src->chunk[chunkno].size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
- } /* end for */
-
- /* Loop through chunks to copy chunk information */
for(chunkno = 0; chunkno < oh_src->nchunks; chunkno++) {
- chunk_size = oh_src->chunk[chunkno].size;
+ size_t chunk_size = oh_src->chunk[chunkno].size;
+
+ /* '0th' chunk is preceded by object header prefix */
+ if(0 == chunkno) {
+ /* Allocate file space for the first chunk & object header prefix */
+ if(HADDR_UNDEF == (addr_new = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + chunk_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
- /* copy chunk information */
- chunk[chunkno].dirty = oh_src->chunk[chunkno].dirty;
- chunk[chunkno].size = chunk_size;
+ /* Set first chunk's address */
+ oh_dst->chunk[0].addr = addr_new + (hsize_t)hdr_size;
+ } /* end if */
+ else {
+ if(HADDR_UNDEF == (oh_dst->chunk[chunkno].addr = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)chunk_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
+ } /* end else */
- /* create memory image for the new chunk */
- if(NULL == (chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image,chunk_size)))
+ /* Create memory image for the new chunk */
+ if(NULL == (oh_dst->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, chunk_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- /* copy the chunk image from source to destination in memory */
+ /* Copy the chunk image from source to destination in memory */
/* (This copies over all the messages which don't require special
* callbacks to fix them up.)
*/
- HDmemcpy(chunk[chunkno].image, oh_src->chunk[chunkno].image, chunk_size);
+ HDmemcpy(oh_dst->chunk[chunkno].image, oh_src->chunk[chunkno].image, chunk_size);
- /* Loop through messages, to fix up any which refer to addresses in the source file, etc. */
- for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
- const H5O_class_t *copy_type;
+ /* Set dest. chunk information */
+ oh_dst->chunk[chunkno].dirty = TRUE;
+ oh_dst->chunk[chunkno].size = chunk_size;
+ } /* end for */
- mesg_src = &(oh_src->mesg[mesgno]);
- /* check if the message belongs to this chunk */
- if(mesg_src->chunkno != chunkno)
- continue;
+ /* Initialize size of message list */
+ oh_dst->alloc_nmesgs = oh_dst->nmesgs = oh_src->nmesgs;
- if (mesg_src->flags & H5O_FLAG_SHARED)
- copy_type = H5O_SHARED;
- else
- copy_type = mesg_src->type;
+ /* Allocate memory for message array */
+ if(NULL == (oh_dst->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh_dst->alloc_nmesgs)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- /* copy this message into destination file */
- HDassert(copy_type);
- if(copy_type->copy_file) {
- void *dst_native; /* Pointer to copy of native information for current message */
-
- /*
- * Decode the message if necessary. If the message is shared then d
- * a shared message, ignoring the message type.
- */
- if(NULL == mesg_src->native) {
- /* Decode the message if necessary */
- HDassert(copy_type->decode);
- if(NULL == (mesg_src->native = (copy_type->decode)(oloc_src->file, dxpl_id, mesg_src->raw)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode a message")
- } /* end if (NULL == mesg_src->native) */
-
- /* Copy the source message */
- if(H5O_CONT_ID == copy_type->id) {
- if((dst_native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
- oloc_dst->file, dxpl_id, map_list, chunk)) == NULL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
- } /* end if */
- else {
- if((dst_native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
- oloc_dst->file, dxpl_id, map_list, NULL)) == NULL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
- } /* end else */
-
- /* Calculate address in destination raw chunk */
- p = chunk[chunkno].image + (mesg_src->raw - oh_src->chunk[chunkno].image);
+ /* Copy basic information about messages */
+ HDmemcpy(oh_dst->mesg, oh_src->mesg, oh_dst->alloc_nmesgs * sizeof(H5O_mesg_t));
- /*
- * Encode the message. If the message is shared then we
- * encode a Shared Object message instead of the object
- * which is being shared.
- */
- if((copy_type->encode)(oloc_dst->file, p, dst_native) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
+ /* "pre copy" pass over messages, to gather information for actual message copy operation */
+ /* (for messages which depend on information from other messages) */
+ /* (also resets various destination message information) */
+ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
+ /* Set up convenience variables */
+ mesg_src = &(oh_src->mesg[mesgno]);
+ mesg_dst = &(oh_dst->mesg[mesgno]);
- /* Release native destination info */
- H5O_free_real(copy_type, dst_native);
- } /* end if (mesg_src->type && mesg_src->type->copy_file) */
- } /* end of mesgno loop */
+ /* Sanity check */
+ HDassert(!mesg_src->dirty); /* Should be cleared by earlier call to flush messages */
- /* Write the object header to the file if this is the first chunk */
- if(chunkno == 0)
- if(H5F_block_write(oloc_dst->file, H5FD_MEM_OHDR, addr_new, hdr_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk")
+ /* Fix up destination message pointers */
+ mesg_dst->native = NULL;
+ mesg_dst->raw = oh_dst->chunk[mesg_dst->chunkno].image + (mesg_src->raw - oh_src->chunk[mesg_src->chunkno].image);
- /* Write this chunk into disk */
- if(H5F_block_write(oloc_dst->file, H5FD_MEM_OHDR, chunk[chunkno].addr, chunk[chunkno].size, dxpl_id, chunk[chunkno].image) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk")
- } /* end of chunkno loop */
+ /* Check for shared message to operate on */
+ if(mesg_src->flags & H5O_FLAG_SHARED)
+ copy_type = H5O_MSG_SHARED;
+ else
+ copy_type = mesg_src->type;
+ HDassert(copy_type);
+ if(copy_type->pre_copy_file) {
+ /*
+ * Decode the message if necessary. If the message is shared then do
+ * a shared message, ignoring the message type.
+ */
+ if(NULL == mesg_src->native) {
+ /* Decode the message if necessary */
+ HDassert(copy_type->decode);
+ if(NULL == (mesg_src->native = (copy_type->decode)(oloc_src->file, dxpl_id, mesg_src->raw)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode a message")
+ } /* end if (NULL == mesg_src->native) */
+
+ /* Perform "pre copy" operation on messge */
+ if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
+ } /* end if */
+ } /* end for */
- /* Protect destination object header, so we can modify messages in it */
- if(NULL == (oh_dst = H5AC_protect(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
- HDassert(oh_dst->nmesgs == oh_src->nmesgs);
+ /* "copy" pass over messages, to perform main message copying */
+ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
+ /* Set up convenience variables */
+ mesg_src = &(oh_src->mesg[mesgno]);
+ mesg_dst = &(oh_dst->mesg[mesgno]);
+
+ /* Check for shared message to operate on */
+ if (mesg_src->flags & H5O_FLAG_SHARED)
+ copy_type = H5O_MSG_SHARED;
+ else
+ copy_type = mesg_src->type;
+
+ /* copy this message into destination file */
+ HDassert(copy_type);
+ if(copy_type->copy_file) {
+ /*
+ * Decode the message if necessary. If the message is shared then do
+ * a shared message, ignoring the message type.
+ */
+ if(NULL == mesg_src->native) {
+ /* Decode the message if necessary */
+ HDassert(copy_type->decode);
+ if(NULL == (mesg_src->native = (copy_type->decode)(oloc_src->file, dxpl_id, mesg_src->raw)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode a message")
+ } /* end if (NULL == mesg_src->native) */
+
+ /* Copy the source message */
+ if(H5O_CONT_ID == mesg_src->type->id) {
+ if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
+ oloc_dst->file, dxpl_id, map_list, oh_dst->chunk)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ } /* end if */
+ else {
+ if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
+ oloc_dst->file, dxpl_id, map_list, udata)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ } /* end else */
+
+ /*
+ * Encode the message. If the message is shared then we
+ * encode a Shared Object message instead of the object
+ * which is being shared.
+ */
+ if((copy_type->encode)(oloc_dst->file, mesg_dst->raw, mesg_dst->native) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
+ } /* end if (mesg_src->type->copy_file) */
+ } /* end of mesgno loop */
+
+
+ /* Set the dest. object location to the first chunk address */
+ oloc_dst->addr = addr_new;
/* Allocate space for the address mapping of the object copied */
if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
@@ -4338,14 +4267,14 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src,
if(H5SL_insert(map_list, addr_map, &(addr_map->src_addr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
- /* "post copy" loop over messages */
+ /* "post copy" loop over messages, to fix up any messages which require a complete object header for destination object */
for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
- const H5O_class_t *copy_type;
-
+ /* Set up convenience variables */
mesg_src = &(oh_src->mesg[mesgno]);
+ /* Check for shared message to operate on */
if(mesg_src->flags & H5O_FLAG_SHARED)
- copy_type = H5O_SHARED;
+ copy_type = H5O_MSG_SHARED;
else
copy_type = mesg_src->type;
@@ -4358,52 +4287,48 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src,
HDassert(mesg_dst->type == mesg_src->type);
/* Make certain the destination's native info is available */
- LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst)
+ LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst, FAIL)
/* Perform "post copy" operation on messge */
if((copy_type->post_copy_file)(oloc_src->file, mesg_src->native, oloc_dst, mesg_dst->native, &modified, dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
/* Mark message and header as dirty if the destination message was modified */
- if(modified) {
+ if(modified)
mesg_dst->dirty = TRUE;
- dst_oh_flags |= H5AC__DIRTIED_FLAG;
- } /* end if */
} /* end if */
} /* end for */
+ /* Indicate that the destination address will no longer be locked */
+ addr_map->is_locked = FALSE;
+
+ /* Increment object header's reference count, if any descendents have created links to link to this object */
+ if(addr_map->inc_ref_count)
+ oh_dst->nlink += addr_map->inc_ref_count;
+
+ /* Insert destination object header in cache */
+ if(H5AC_set(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__DIRTIED_FLAG) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header")
+
done:
/* Release pointer to source object header and it's derived objects */
if(oh_src != NULL) {
- /* Release all the chunks used to copy messages */
- if(chunk) {
- for(chunkno = 0; chunkno < oh_src->nchunks; chunkno++)
- H5FL_BLK_FREE(chunk_image, chunk[chunkno].image);
- H5FL_SEQ_FREE(H5O_chunk_t, chunk);
- } /* end if */
-
/* Unprotect the source object header */
if(H5AC_unprotect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, oh_src, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
} /* end if */
/* Release pointer to destination object header */
- if(oh_dst != NULL) {
- /* Perform operations on address mapping for object, if it's in use */
- if(addr_map) {
- /* Indicate that the destination address will no longer be locked */
- addr_map->is_locked = FALSE;
-
- /* Increment object header's reference count, if any descendents have created links to link to this object */
- if(addr_map->inc_ref_count) {
- oh_dst->nlink += addr_map->inc_ref_count;
- dst_oh_flags |= H5AC__DIRTIED_FLAG;
- } /* end if */
- } /* end if */
+ if(ret_value < 0 && oh_dst) {
+ if(H5O_dest(oloc_dst->file, oh_dst) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
+ } /* end if */
- /* Unprotect the destination object header */
- if(H5AC_unprotect(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, dst_oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ /* Release user data for particular type of object to copy */
+ if(udata) {
+ HDassert(obj_class);
+ HDassert(obj_class->free_copy_file_udata);
+ (obj_class->free_copy_file_udata)(udata);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -4571,16 +4496,16 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth)
+H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
+ 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 */
- assert(type_id>=0 && type_id < (hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0])));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert(type_id < NELMTS(H5O_msg_class_g));
+ type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
assert(type);
assert(type->debug);
assert(f);
@@ -4675,15 +4600,14 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
}
/* debug each message */
- if (NULL==(sequence = H5MM_calloc(NELMTS(message_type_g)*sizeof(int))))
+ 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(f) + oh->mesg[i].raw_size;
HDfprintf(stream, "%*sMessage %d...\n", indent, "", i);
/* check for bad message id */
- if (oh->mesg[i].type->id < 0 ||
- oh->mesg[i].type->id >= (int)NELMTS(message_type_g)) {
+ 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;
@@ -4732,8 +4656,8 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
/* decode the message */
if (oh->mesg[i].flags & H5O_FLAG_SHARED) {
- decode = H5O_SHARED->decode;
- debug = H5O_SHARED->debug;
+ decode = H5O_MSG_SHARED->decode;
+ debug = H5O_MSG_SHARED->debug;
} else {
decode = oh->mesg[i].type->decode;
debug = oh->mesg[i].type->debug;