summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5A.c18
-rw-r--r--src/H5HG.c2
-rw-r--r--src/H5HGprivate.h2
-rw-r--r--src/H5O.c500
-rw-r--r--src/H5Oattr.c296
-rw-r--r--src/H5Obogus.c1
-rw-r--r--src/H5Ocont.c1
-rw-r--r--src/H5Odtype.c1
-rw-r--r--src/H5Oefl.c1
-rw-r--r--src/H5Ofill.c2
-rw-r--r--src/H5Olayout.c1
-rw-r--r--src/H5Omtime.c2
-rw-r--r--src/H5Oname.c1
-rw-r--r--src/H5Onull.c1
-rw-r--r--src/H5Opkg.h8
-rw-r--r--src/H5Opline.c1
-rw-r--r--src/H5Oprivate.h3
-rw-r--r--src/H5Osdspace.c1
-rw-r--r--src/H5Oshared.c302
-rw-r--r--src/H5Ostab.c1
-rw-r--r--src/H5Tcommit.c66
-rw-r--r--src/H5Tprivate.h2
23 files changed, 922 insertions, 294 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 30dfc9b..67f5957 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -76,6 +76,9 @@ Bug Fixes since HDF5-1.6.0 release
Library
-------
+ - Correctly create reference to shared datatype in attribute, instead
+ of making a copy of the shared datatype in the attribute.
+ QAK - 2003/10/01
- Revert changes which caused files >2GB to fail when created with
MPI-I/O file driver on certain platforms. QAK - 2003/09/16
- Allow compound datatypes to grow in size. SLU - 2003/09/10
diff --git a/src/H5A.c b/src/H5A.c
index dccef50..f60c0ac 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -250,8 +250,22 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
if (H5G_ent_copy(&(attr->ent),ent,H5G_COPY_DEEP)<0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
- /* Compute the internal sizes */
- attr->dt_size=H5O_raw_size(H5O_DTYPE_ID,attr->ent.file,type);
+ /* Compute the size of pieces on disk */
+ if(H5T_committed(attr->dt)) {
+ H5O_shared_t sh_mesg;
+
+ /* Reset shared message information */
+ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+
+ /* Get shared message information for datatype */
+ if (H5O_get_share(H5O_DTYPE_ID,attr->ent.file, type, &sh_mesg/*out*/)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
+
+ /* Compute shared message size for datatype */
+ attr->dt_size=H5O_raw_size(H5O_SHARED_ID,attr->ent.file,&sh_mesg);
+ } /* end if */
+ else
+ attr->dt_size=H5O_raw_size(H5O_DTYPE_ID,attr->ent.file,type);
assert(attr->dt_size>0);
attr->ds_size=H5O_raw_size(H5O_SDSPACE_ID,attr->ent.file,&(space->extent.u.simple));
assert(attr->ds_size>0);
diff --git a/src/H5HG.c b/src/H5HG.c
index 98372eb..47df258 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -891,7 +891,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5HG_link (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, int adjust)
+H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust)
{
H5HG_heap_t *heap = NULL;
int ret_value; /* Return value */
diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h
index 8e589e1..56589f9 100644
--- a/src/H5HGprivate.h
+++ b/src/H5HGprivate.h
@@ -43,7 +43,7 @@ typedef struct H5HG_heap_t H5HG_heap_t;
H5_DLL herr_t H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj,
H5HG_t *hobj/*out*/);
H5_DLL void *H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object);
-H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, int adjust);
+H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust);
H5_DLL herr_t H5HG_remove(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj);
/* Debugging functions */
diff --git a/src/H5O.c b/src/H5O.c
index f436e29..d9ef4ff 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -49,15 +49,12 @@
static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5G_entry_t *ent/*out*/, haddr_t header);
static herr_t H5O_reset_real(const H5O_class_t *type, void *native);
-static void * H5O_free_real(const H5O_class_t *type, void *mesg);
static void * H5O_copy_real(const H5O_class_t *type, const void *mesg,
void *dst);
static int H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type,
hid_t dxpl_id);
static htri_t H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type,
int sequence, hid_t dxpl_id);
-static void * H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type,
- int sequence, void *mesg, 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,
H5HG_t *hobj/*out*/);
@@ -76,6 +73,12 @@ static unsigned H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type,
static unsigned H5O_alloc_extend_chunk(H5O_t *oh, unsigned chunkno, size_t size);
static unsigned H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size);
static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
+static herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg);
+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);
+static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
+ const void *mesg, unsigned flags);
/* Metadata cache callbacks */
static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
@@ -119,7 +122,7 @@ static const H5O_class_t *const message_type_g[] = {
H5O_ATTR, /*0x000C Attribute list */
H5O_NAME, /*0x000D Object name */
H5O_MTIME, /*0x000E Object modification date and time */
- NULL, /*0x000F Shared header message */
+ 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 */
@@ -582,7 +585,8 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* decode next object header continuation message */
for (chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) {
if (H5O_CONT_ID == oh->mesg[curmesg].type->id) {
- H5O_cont_t *cont = NULL;
+ H5O_cont_t *cont;
+
cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw, NULL);
oh->mesg[curmesg].native = cont;
chunk_addr = cont->addr;
@@ -1003,8 +1007,7 @@ H5O_free (hid_t type_id, void *mesg)
assert(type);
/* Call the "real" free routine */
- if((ret_value=H5O_free_real(type, mesg))==NULL)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to free object header");
+ ret_value=H5O_free_real(type, mesg);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1028,7 +1031,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5O_free_real(const H5O_class_t *type, void *mesg)
{
void * ret_value=NULL; /* Return value */
@@ -1156,7 +1159,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5O_link(H5G_entry_t *ent, int adjust, hid_t dxpl_id)
+H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
{
H5O_t *oh = NULL;
hbool_t deleted=FALSE; /* Whether the object was deleted as a result of this action */
@@ -1505,7 +1508,7 @@ done:
* actually destroys the object in the cache.
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
{
H5O_t *oh = NULL;
@@ -1548,28 +1551,9 @@ H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mes
* message in the global heap or some other object header.
*/
H5O_shared_t *shared;
- void *tmp_buf, *tmp_mesg;
shared = (H5O_shared_t *)(oh->mesg[idx].native);
- if (shared->in_gh) {
- if (NULL==(tmp_buf = H5HG_read (ent->file, dxpl_id, &(shared->u.gh), NULL)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to read shared message from global heap");
- tmp_mesg = (type->decode)(ent->file, dxpl_id, tmp_buf, shared);
- tmp_buf = H5MM_xfree (tmp_buf);
- if (!tmp_mesg)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to decode object header shared message");
- if (mesg) {
- HDmemcpy (mesg, tmp_mesg, type->native_size);
- H5MM_xfree (tmp_mesg);
- } else {
- ret_value = tmp_mesg;
- }
- } else {
- ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id);
- if (type->set_share &&
- (type->set_share)(ent->file, ret_value, shared)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information");
- }
+ ret_value=H5O_shared_read(ent->file,dxpl_id,shared,type,mesg);
} else {
/*
* The message is not shared, but rather exists in the object
@@ -1590,7 +1574,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_find_in_ohdr
+ * Function: H5O_find_in_ohdr
*
* Purpose: Find a message in the object header without consulting
* a symbol table entry.
@@ -1622,6 +1606,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
/* Check args */
assert(f);
+ assert(oh);
assert(type_p);
/* Scan through the messages looking for the right one */
@@ -1789,7 +1774,6 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
int sequence;
unsigned idx; /* Index of message to modify */
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
- size_t size=0;
H5O_shared_t sh_mesg;
int ret_value;
@@ -1815,64 +1799,24 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
continue;
if (++sequence == overwrite)
break;
- }
+ } /* end for */
/* Was the right message found? */
- if (overwrite >= 0 &&
- (idx >= oh->nmesgs || sequence != overwrite)) {
-
+ if (overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) {
/* But can we insert a new one with this sequence number? */
- if (overwrite == sequence + 1) {
+ if (overwrite == sequence + 1)
overwrite = -1;
- } else {
+ else
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found");
- }
- }
+ } /* end if */
+
+ /* Check for creating new message */
if (overwrite < 0) {
- /* Allocate space for the new message */
- if (flags & H5O_FLAG_SHARED) {
- HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
-
- if (NULL==type->get_share)
- HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable");
- if ((type->get_share)(ent->file, mesg, &sh_mesg/*out*/)<0) {
- /*
- * If the message isn't shared then turn off the shared bit
- * and treat it as an unshared message.
- */
- H5E_clear (NULL);
- flags &= ~H5O_FLAG_SHARED;
- } else if (sh_mesg.in_gh) {
- /*
- * The shared message is stored in the global heap.
- * Increment the reference count on the global heap message.
- */
- if (H5HG_link (ent->file, dxpl_id, &(sh_mesg.u.gh), 1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
- } else {
- /*
- * The shared message is stored in some other object header.
- * The other object header must be in the same file as the
- * new object header. Increment the reference count on that
- * object header.
- */
- if (sh_mesg.u.ent.file->shared != ent->file->shared)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
- if (H5O_link (&(sh_mesg.u.ent), 1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
- }
- }
- /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */
- if (0== (flags & H5O_FLAG_SHARED)) {
- size = (type->raw_size) (ent->file, mesg);
- if (size>=H5O_MAX_SIZE)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)");
- }
- idx = H5O_alloc(ent->file, oh, type, size);
- if (idx == UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message");
+ /* Create a new message */
+ if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id))==UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
+
+ /* Set the correct sequence number for the message created */
sequence++;
} else if (oh->mesg[idx].flags & H5O_FLAG_CONSTANT) {
@@ -1881,30 +1825,14 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message");
}
- /* Set pointer to the correct message */
- idx_msg=&oh->mesg[idx];
-
- /* Copy the native value into the object header */
- if (flags & H5O_FLAG_SHARED) {
- if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t));
- } else {
- if (idx_msg->native)
- H5O_reset_real(idx_msg->type, idx_msg->native);
- idx_msg->native = (type->copy) (mesg, idx_msg->native);
- if (NULL == idx_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
- }
+ /* Write the information to the message */
+ if(H5O_write_mesg(oh,idx,type,mesg,flags)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
/* Update the modification time message if any */
if(update_time)
H5O_touch_oh(ent->file, oh, FALSE);
- idx_msg->flags = flags;
- idx_msg->dirty = TRUE;
- oh->cache_info.dirty = TRUE;
-
/* Set return value */
ret_value = sequence;
@@ -2007,13 +1935,6 @@ done:
* Purpose: Simplified version of H5O_modify, used when creating a new
* object header message (usually during object creation)
*
- * Modifies an existing message or creates a new message.
- * The cache fields in that symbol table entry ENT are *not*
- * updated, you must do that separately because they often
- * depend on multiple object header messages. Besides, we
- * don't know which messages will be constant and which will
- * not.
- *
* Return: Success: The sequence number of the message that
* was created.
*
@@ -2064,13 +1985,6 @@ done:
* Purpose: Simplified version of H5O_modify, used when creating a new
* object header message (usually during object creation)
*
- * Modifies an existing message or creates a new message.
- * The cache fields in that symbol table entry ENT are *not*
- * updated, you must do that separately because they often
- * depend on multiple object header messages. Besides, we
- * don't know which messages will be constant and which will
- * not.
- *
* Return: Success: The sequence number of the message that
* was created.
*
@@ -2089,8 +2003,6 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
unsigned flags, const void *mesg)
{
unsigned idx; /* Index of message to modify */
- H5O_mesg_t *idx_msg; /* Pointer to message to modify */
- size_t size=0;
H5O_shared_t sh_mesg;
int ret_value = FAIL;
@@ -2103,76 +2015,143 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
assert(0==(flags & ~H5O_FLAG_BITS));
assert(mesg);
- /* Allocate space for the new message */
- if (flags & H5O_FLAG_SHARED) {
- HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+ /* Create a new message */
+ if((idx=H5O_new_mesg(f,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id))==UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
+
+ /* Write the information to the message */
+ if(H5O_write_mesg(oh,idx,type,mesg,flags)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
+
+ /* Set return value */
+ ret_value = idx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_append_real () */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_new_mesg
+ *
+ * Purpose: Create a new message in an object header
+ *
+ * Return: Success: Index of message
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+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)
+{
+ size_t size; /* Size of space allocated for object header */
+ unsigned ret_value=UFAIL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5O_new_mesg);
- if (NULL==type->get_share)
- HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable");
- if ((type->get_share)(f, mesg, &sh_mesg/*out*/)<0) {
+ /* check args */
+ assert(f);
+ assert(oh);
+ assert(flags);
+ assert(orig_type);
+ assert(orig_mesg);
+ assert(sh_mesg);
+ assert(new_mesg);
+ assert(new_type);
+
+ /* Check for shared message */
+ if (*flags & H5O_FLAG_SHARED) {
+ HDmemset(sh_mesg,0,sizeof(H5O_shared_t));
+
+ if (NULL==orig_type->get_share)
+ HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable");
+ if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/)<0) {
/*
* If the message isn't shared then turn off the shared bit
* and treat it as an unshared message.
*/
H5E_clear (NULL);
- flags &= ~H5O_FLAG_SHARED;
- } else if (sh_mesg.in_gh) {
- /*
- * The shared message is stored in the global heap.
- * Increment the reference count on the global heap message.
- */
- if (H5HG_link (f, dxpl_id, &(sh_mesg.u.gh), 1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(f, &sh_mesg);
+ *flags &= ~H5O_FLAG_SHARED;
} else {
- /*
- * The shared message is stored in some other object header.
- * The other object header must be in the same file as the
- * new object header. Increment the reference count on that
- * object header.
- */
- if (sh_mesg.u.ent.file->shared != f->shared)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
- if (H5O_link (&(sh_mesg.u.ent), 1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(f, &sh_mesg);
- }
- }
- /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */
- if (0== (flags & H5O_FLAG_SHARED)) {
- size = (type->raw_size) (f, mesg);
- if (size>=H5O_MAX_SIZE)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)");
- }
- if ((idx = H5O_alloc(f, oh, type, size)) == UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message");
-
+ /* Change type & message to use shared information */
+ *new_type=H5O_SHARED;
+ *new_mesg=sh_mesg;
+ } /* end else */
+ } /* end if */
+ else {
+ *new_type=orig_type;
+ *new_mesg=orig_mesg;
+ } /* end else */
+
+ /* Compute the size needed to store the message on disk */
+ if ((size = ((*new_type)->raw_size) (f, *new_mesg)) >=H5O_MAX_SIZE)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large (16k max)");
+
+ /* Allocate space in the object headed for the message */
+ if ((ret_value = H5O_alloc(f, oh, orig_type, size)) == UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message");
+
+ /* Increment any links in message */
+ if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_new_mesg() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_write_mesg
+ *
+ * Purpose: Write message to object header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
+ const void *mesg, unsigned flags)
+{
+ H5O_mesg_t *idx_msg; /* Pointer to message to modify */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5O_write_mesg);
+
+ /* check args */
+ assert(oh);
+ assert(type);
+ assert(mesg);
+
/* Set pointer to the correct message */
idx_msg=&oh->mesg[idx];
- /* Copy the native value into the object header */
- if (flags & H5O_FLAG_SHARED) {
- if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t));
- } else {
- if (idx_msg->native)
- H5O_reset_real(idx_msg->type, idx_msg->native);
- idx_msg->native = (type->copy) (mesg, idx_msg->native);
- if (NULL == idx_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
- }
-
+ /* Reset existing native information */
+ H5O_reset_real(type, idx_msg->native);
+
+ /* Copy the native value for the message */
+ if (NULL == (idx_msg->native = (type->copy) (mesg, idx_msg->native)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
+
idx_msg->flags = flags;
idx_msg->dirty = TRUE;
oh->cache_info.dirty = TRUE;
- /* Set return value */
- ret_value = idx;
-
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5O_append_real () */
+} /* end H5O_write_mesg() */
/*-------------------------------------------------------------------------
@@ -2478,10 +2457,10 @@ done:
static herr_t
H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t dxpl_id)
{
- H5O_t *oh = NULL;
+ H5O_t *oh = NULL;
+ H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
int seq, nfailed = 0;
- unsigned u;
- H5O_shared_t *sh_mesg = NULL;
+ unsigned u;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5O_remove_real);
@@ -2499,40 +2478,32 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t d
if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
- for (u = seq = 0; u < oh->nmesgs; u++) {
- if (type->id != oh->mesg[u].type->id)
+ for (u = seq = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ if (type->id != curr_msg->type->id)
continue;
if (seq++ == sequence || H5O_ALL == sequence) {
+
/*
* Keep track of how many times we failed trying to remove constant
* messages.
*/
- if (oh->mesg[u].flags & H5O_FLAG_CONSTANT) {
+ if (curr_msg->flags & H5O_FLAG_CONSTANT) {
nfailed++;
continue;
- }
+ } /* end if */
- if (oh->mesg[u].flags & H5O_FLAG_SHARED) {
- if (NULL==oh->mesg[u].native) {
- sh_mesg = (H5O_SHARED->decode)(ent->file, dxpl_id, oh->mesg[u].raw,
- NULL);
- if (NULL==(oh->mesg[u].native = sh_mesg))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode shared message info");
- }
- if (sh_mesg->in_gh) {
- if (H5HG_link (ent->file, dxpl_id, &(sh_mesg->u.gh), -1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to decrement link count on shared message");
- } else {
- if (H5O_link (&(sh_mesg->u.ent), -1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to decrement link count on shared message");
- }
- }
+ /* Free any space referred to in the file from this message */
+ if(H5O_delete_mesg(ent->file,dxpl_id,curr_msg)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
/* change message type to nil and zero it */
- oh->mesg[u].type = H5O_NULL;
- HDmemset(oh->mesg[u].raw, 0, oh->mesg[u].raw_size);
- oh->mesg[u].native = H5O_free_real(type, oh->mesg[u].native);
- oh->mesg[u].dirty = TRUE;
+ curr_msg->type = H5O_NULL;
+ HDmemset(curr_msg->raw, 0, curr_msg->raw_size);
+ if(curr_msg->flags & H5O_FLAG_SHARED)
+ curr_msg->native = H5O_free_real(H5O_SHARED, curr_msg->native);
+ else
+ curr_msg->native = H5O_free_real(type, curr_msg->native);
+ curr_msg->dirty = TRUE;
oh->cache_info.dirty = TRUE;
H5O_touch_oh(ent->file, oh, FALSE);
}
@@ -3095,6 +3066,51 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_get_share
+ *
+ * Purpose: Call the 'get_share' method for a
+ * particular class of object header.
+ *
+ * Return: Success: Non-negative, and SHARE describes the shared
+ * object.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 2 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share)
+{
+ const H5O_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 */
+ 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);
+ assert (type->get_share);
+ assert (f);
+ assert (mesg);
+ assert (share);
+
+ /* Compute the raw data size for the mesg */
+ if ((ret_value = (type->get_share)(f, mesg, share))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_get_share() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_delete
*
* Purpose: Delete an object header from a file. This frees the file
@@ -3173,33 +3189,13 @@ H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
assert (f);
assert (oh);
- /* Walk through the list of object header messages, asking each on to
+ /* Walk through the list of object header messages, asking each one to
* delete any file space used
*/
for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
- const H5O_class_t *type = NULL;
-
- /* Don't handle shared messages yet */
- assert(!(curr_msg->flags & H5O_FLAG_SHARED));
-
- /* Get the message's type */
- type = curr_msg->type;
-
- /* Check if there is a file space deletion callback for this type of message */
- if(type->del) {
- /*
- * Decode the message if necessary.
- */
- if (NULL == curr_msg->native) {
- assert(type->decode);
- curr_msg->native = (type->decode) (f, dxpl_id, curr_msg->raw, NULL);
- if (NULL == curr_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message");
- } /* end if */
-
- if ((type->del)(f, dxpl_id, curr_msg->native)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
- } /* end if */
+ /* Free any space referred to in the file from this message */
+ if(H5O_delete_mesg(f,dxpl_id,curr_msg)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
} /* end for */
/* Free all the chunks for the object header */
@@ -3227,6 +3223,62 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_delete_mesg
+ *
+ * Purpose: Internal function to:
+ * Delete an object header message from a file. This frees the file
+ * space used for anything referred to in the object header message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * September 26 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg)
+{
+ const H5O_class_t *type; /* Type of object to free */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5O_delete_mesg);
+
+ /* Check args */
+ assert (f);
+ assert (mesg);
+
+ /* Get the message to free's type */
+ if(mesg->flags & H5O_FLAG_SHARED)
+ type=H5O_SHARED;
+ else
+ type = mesg->type;
+
+ /* Check if there is a file space deletion callback for this type of message */
+ if(type->del) {
+ /*
+ * Decode the message if necessary.
+ */
+ if (NULL == mesg->native) {
+ assert(type->decode);
+ mesg->native = (type->decode) (f, dxpl_id, mesg->raw, NULL);
+ if (NULL == mesg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message");
+ } /* end if */
+
+ if ((type->del)(f, dxpl_id, mesg->native)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_delete_msg() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_debug_id
*
* Purpose: Act as a proxy for calling the 'debug' method for a
@@ -3410,7 +3462,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
decode = oh->mesg[i].type->decode;
debug = oh->mesg[i].type->debug;
}
- if (NULL==oh->mesg[i].native && oh->mesg[i].type->decode)
+ if (NULL==oh->mesg[i].native && decode)
oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw, NULL);
if (NULL==oh->mesg[i].native)
debug = NULL;
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index f1217a9..fdf24a6 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -35,6 +35,8 @@ static void *H5O_attr_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_sha
static void *H5O_attr_copy (const void *_mesg, void *_dest);
static size_t H5O_attr_size (H5F_t *f, const void *_mesg);
static herr_t H5O_attr_reset (void *_mesg);
+static herr_t H5O_attr_delete (H5F_t *f, hid_t dxpl_id, const void *_mesg);
+static herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
static herr_t H5O_attr_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -49,14 +51,22 @@ const H5O_class_t H5O_ATTR[1] = {{
H5O_attr_size, /* size of raw message */
H5O_attr_reset, /* reset method */
NULL, /* free method */
- NULL, /* file delete method */
+ H5O_attr_delete, /* file delete method */
+ H5O_attr_link, /* link method */
NULL, /* get share method */
NULL, /* set share method */
H5O_attr_debug, /* debug the message */
}};
+/* This is the initial version, which does not have support for shared datatypes */
#define H5O_ATTR_VERSION 1
+/* This version allows support for shared datatypes */
+#define H5O_ATTR_VERSION_NEW 2
+
+/* Flags for attribute flag encoding */
+#define H5O_ATTR_FLAG_TYPE_SHARED 0x01
+
/* Interface initialization */
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
@@ -99,6 +109,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
H5S_simple_t *simple; /*simple dimensionality information */
size_t name_len; /*attribute name length */
int version; /*message version number*/
+ unsigned flags=0; /* Attribute flags */
H5A_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_attr_decode, NULL);
@@ -112,11 +123,14 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
/* Version number */
version = *p++;
- if (version!=H5O_ATTR_VERSION)
+ if (version!=H5O_ATTR_VERSION && version!=H5O_ATTR_VERSION_NEW)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for attribute message");
- /* Reserved */
- p++;
+ /* Get the flags byte if we have a later version of the attribute */
+ if(version>H5O_ATTR_VERSION)
+ flags = *p++;
+ else
+ p++; /* Byte is unused when version<2 */
/*
* Decode the sizes of the parts of the attribute. The sizes stored in
@@ -130,12 +144,34 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
if (NULL==(attr->name=H5MM_malloc(name_len)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
HDmemcpy(attr->name,p,name_len);
- p += H5O_ALIGN(name_len); /* advance the memory pointer */
+ if(version < H5O_ATTR_VERSION_NEW)
+ p += H5O_ALIGN(name_len); /* advance the memory pointer */
+ else
+ p += name_len; /* advance the memory pointer */
/* decode the attribute datatype */
- if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p,NULL))==NULL)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype");
- p += H5O_ALIGN(attr->dt_size);
+ if (flags & H5O_ATTR_FLAG_TYPE_SHARED) {
+ H5O_shared_t *shared; /* Shared information */
+
+ /* Get the shared information */
+ if (NULL == (shared = (H5O_SHARED->decode) (f, dxpl_id, p, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message");
+
+ /* Get the actual datatype information */
+ if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_DTYPE, NULL))==NULL)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype");
+
+ /* Free the shared information */
+ H5O_free_real(H5O_SHARED, shared);
+ } /* end if */
+ else {
+ if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p,NULL))==NULL)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype");
+ } /* end else */
+ if(version < H5O_ATTR_VERSION_NEW)
+ p += H5O_ALIGN(attr->dt_size);
+ else
+ p += attr->dt_size;
/* decode the attribute dataspace */
if (NULL==(attr->ds = H5FL_CALLOC(H5S_t)))
@@ -159,7 +195,10 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
/* Default to entire dataspace being selected */
if(H5S_select_all(attr->ds,0)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection");
- p += H5O_ALIGN(attr->ds_size);
+ if(version < H5O_ATTR_VERSION_NEW)
+ p += H5O_ALIGN(attr->ds_size);
+ else
+ p += attr->ds_size;
/* Compute the size of the data */
H5_ASSIGN_OVERFLOW(attr->data_size,H5S_get_simple_extent_npoints(attr->ds)*H5T_get_size(attr->dt),hsize_t,size_t);
@@ -206,9 +245,11 @@ done:
static herr_t
H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
{
- const H5A_t *attr = (const H5A_t *) mesg;
- size_t name_len; /* Attribute name length */
- herr_t ret_value=SUCCEED; /* Return value */
+ const H5A_t *attr = (const H5A_t *) mesg;
+ size_t name_len; /* Attribute name length */
+ unsigned version; /* Attribute version */
+ hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_attr_encode, FAIL);
@@ -217,16 +258,31 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
assert(p);
assert(attr);
- /* Version */
- *p++ = H5O_ATTR_VERSION;
+ /* Check whether datatype is shared */
+ if(H5T_committed(attr->dt))
+ type_shared = TRUE;
+ else
+ type_shared = FALSE;
+
+ /* Check which version to write out */
+ if(type_shared)
+ version = H5O_ATTR_VERSION_NEW; /* Write out new version if shared datatype */
+ else
+ version = H5O_ATTR_VERSION;
- /* Reserved */
- *p++ = 0;
+ /* Encode Version */
+ *p++ = version;
+
+ /* Set attribute flags if version >1 */
+ if(version>H5O_ATTR_VERSION)
+ *p++ = (type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 ); /* Set flags for attribute */
+ else
+ *p++ = 0; /* Reserved, for version <2 */
/*
* Encode the lengths of the various parts of the attribute message. The
* encoded lengths are exact but we pad each part except the data to be a
- * multiple of eight bytes.
+ * multiple of eight bytes (in the first version).
*/
name_len = HDstrlen(attr->name)+1;
UINT16ENCODE(p, name_len);
@@ -239,19 +295,47 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
*/
HDmemcpy(p, attr->name, name_len);
HDmemset(p+name_len, 0, H5O_ALIGN(name_len)-name_len);
- p += H5O_ALIGN(name_len);
+ if(version < H5O_ATTR_VERSION_NEW)
+ p += H5O_ALIGN(name_len);
+ else
+ p += name_len;
/* encode the attribute datatype */
- if((H5O_DTYPE->encode)(f,p,attr->dt)<0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype");
- HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size);
- p += H5O_ALIGN(attr->dt_size);
+ if(type_shared) {
+ H5O_shared_t sh_mesg;
+
+ /* Reset shared message information */
+ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+
+ /* Get shared message information from datatype */
+ if ((H5O_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype");
+
+ /* Encode shared message information for datatype */
+ if((H5O_SHARED->encode)(f,p,&sh_mesg)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype");
+ } /* end if */
+ else {
+ /* Encode datatype information */
+ if((H5O_DTYPE->encode)(f,p,attr->dt)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype");
+ } /* end else */
+ if(version < H5O_ATTR_VERSION_NEW) {
+ HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size);
+ p += H5O_ALIGN(attr->dt_size);
+ } /* end if */
+ else
+ p += attr->dt_size;
/* encode the attribute dataspace */
if((H5O_SDSPACE->encode)(f,p,&(attr->ds->extent.u.simple))<0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace");
- HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size);
- p += H5O_ALIGN(attr->ds_size);
+ if(version < H5O_ATTR_VERSION_NEW) {
+ HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size);
+ p += H5O_ALIGN(attr->ds_size);
+ } /* end if */
+ else
+ p += attr->ds_size;
/* Store attribute data */
HDmemcpy(p,attr->data,attr->data_size);
@@ -327,11 +411,13 @@ done:
* Added padding between message parts for alignment.
--------------------------------------------------------------------------*/
static size_t
-H5O_attr_size(H5F_t UNUSED *f, const void *mesg)
+H5O_attr_size(H5F_t UNUSED *f, const void *_mesg)
{
- size_t ret_value = 0;
+ const H5A_t *attr = (const H5A_t *)_mesg;
size_t name_len;
- const H5A_t *attr = (const H5A_t *) mesg;
+ unsigned version; /* Attribute version */
+ hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */
+ size_t ret_value = 0;
FUNC_ENTER_NOAPI(H5O_attr_size, 0);
@@ -339,14 +425,38 @@ H5O_attr_size(H5F_t UNUSED *f, const void *mesg)
name_len = HDstrlen(attr->name)+1;
- ret_value = 2 + /*name size inc. null */
- 2 + /*type size */
- 2 + /*space size */
- 2 + /*reserved */
- H5O_ALIGN(name_len) + /*attribute name */
- H5O_ALIGN(attr->dt_size) + /*data type */
- H5O_ALIGN(attr->ds_size) + /*data space */
- attr->data_size; /*the data itself */
+ /* Check whether datatype is shared */
+ if(H5T_committed(attr->dt))
+ type_shared = TRUE;
+ else
+ type_shared = FALSE;
+
+ /* Check which version to write out */
+ if(type_shared)
+ version = H5O_ATTR_VERSION_NEW; /* Write out new version if shared datatype */
+ else
+ version = H5O_ATTR_VERSION;
+
+ if(version < H5O_ATTR_VERSION_NEW)
+ ret_value = 1 + /*version */
+ 1 + /*reserved */
+ 2 + /*name size inc. null */
+ 2 + /*type size */
+ 2 + /*space size */
+ H5O_ALIGN(name_len) + /*attribute name */
+ H5O_ALIGN(attr->dt_size) + /*data type */
+ H5O_ALIGN(attr->ds_size) + /*data space */
+ attr->data_size; /*the data itself */
+ else
+ ret_value = 1 + /*version */
+ 1 + /*flags */
+ 2 + /*name size inc. null */
+ 2 + /*type size */
+ 2 + /*space size */
+ name_len + /*attribute name */
+ attr->dt_size + /*data type */
+ attr->ds_size + /*data space */
+ attr->data_size; /*the data itself */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -390,6 +500,83 @@ done:
}
+/*-------------------------------------------------------------------------
+ * Function: H5O_attr_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_attr_delete(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg)
+{
+ const H5A_t *attr = (const H5A_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_attr_delete, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(attr);
+
+ /* Check whether datatype is shared */
+ if(H5T_committed(attr->dt)) {
+ /* Decrement the reference count on the shared datatype */
+ if(H5T_link(attr->dt,-1,dxpl_id)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_attr_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_attr_link
+ *
+ * Purpose: Increment reference count on any objects referenced by
+ * message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg)
+{
+ const H5A_t *attr = (const H5A_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_attr_link, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(attr);
+
+ /* Check whether datatype is shared */
+ if(H5T_committed(attr->dt)) {
+ /* Increment the reference count on the shared datatype */
+ if(H5T_link(attr->dt,1,dxpl_id)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_attr_link() */
+
+
/*--------------------------------------------------------------------------
NAME
H5O_attr_debug
@@ -413,6 +600,9 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
int fwidth)
{
const H5A_t *mesg = (const H5A_t *)_mesg;
+ H5O_shared_t sh_mesg; /* Shared message information */
+ void *dt_mesg; /* Pointer to datatype message to dump */
+ herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int)=NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_attr_debug, FAIL);
@@ -436,16 +626,38 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
H5G_ent_debug(f, dxpl_id, &(mesg->ent), stream, indent+3, MAX(0, fwidth-3),
HADDR_UNDEF);
- fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Data type size:",
- (unsigned long)(mesg->dt_size));
fprintf(stream, "%*sData type...\n", indent, "");
- (H5O_DTYPE->debug)(f, dxpl_id, mesg->dt, stream, indent+3, MAX(0, fwidth-3));
+ fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3),
+ "Size:",
+ (unsigned long)(mesg->dt_size));
+ fprintf (stream, "%*s%-*s %s\n", indent+3, "", MAX(0,fwidth-3),
+ "Shared:",
+ (H5T_committed(mesg->dt) ? "Yes" : "No")
+ );
+ if(H5T_committed(mesg->dt)) {
+ /* Reset shared message information */
+ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+
+ /* Get shared message information from datatype */
+ if ((H5O_DTYPE->get_share)(f, mesg->dt, &sh_mesg/*out*/)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't retrieve shared message information");
+
+ debug=H5O_SHARED->debug;
+ dt_mesg=&sh_mesg;
+ } /* end if */
+ else {
+ debug=H5O_DTYPE->debug;
+ dt_mesg=mesg->dt;
+ } /* end else */
+ if(debug)
+ (debug)(f, dxpl_id, dt_mesg, stream, indent+3, MAX(0, fwidth-3));
+ else
+ fprintf(stream, "%*s<No info for this message>\n", indent + 6, "");
- fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Data space size:",
- (unsigned long)(mesg->ds_size));
fprintf(stream, "%*sData space...\n", indent, "");
+ fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3),
+ "Size:",
+ (unsigned long)(mesg->ds_size));
H5S_debug(f, dxpl_id, mesg->ds, stream, indent+3, MAX(0, fwidth-3));
done:
diff --git a/src/H5Obogus.c b/src/H5Obogus.c
index 90b7b3d..b049654 100644
--- a/src/H5Obogus.c
+++ b/src/H5Obogus.c
@@ -58,6 +58,7 @@ const H5O_class_t H5O_BOGUS[1] = {{
NULL, /*free internal memory */
NULL, /*free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_bogus_debug, /*debug the message */
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index 4b54c4a..e8dca5b 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -55,6 +55,7 @@ const H5O_class_t H5O_CONT[1] = {{
NULL, /*reset method */
NULL, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_cont_debug, /*debugging */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 2c943cf..5ab3fb4 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -51,6 +51,7 @@ const H5O_class_t H5O_DTYPE[1] = {{
H5O_dtype_reset, /* reset method */
H5O_dtype_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
H5O_dtype_get_share, /* get share method */
H5O_dtype_set_share, /* set share method */
H5O_dtype_debug, /* debug the message */
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index ec33293..4ecd5f8 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -54,6 +54,7 @@ const H5O_class_t H5O_EFL[1] = {{
H5O_efl_reset, /*reset method */
NULL, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_efl_debug, /*debug the message */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index 13da259..b2595a0 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -61,6 +61,7 @@ const H5O_class_t H5O_FILL[1] = {{
H5O_fill_reset, /*free internal memory */
H5O_fill_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_fill_debug, /*debug the message */
@@ -78,6 +79,7 @@ const H5O_class_t H5O_FILL_NEW[1] = {{
H5O_fill_new_reset, /*free internal memory */
H5O_fill_new_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_fill_new_debug, /*debug the message */
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index fc1eeae..b9a41ec 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -51,6 +51,7 @@ const H5O_class_t H5O_LAYOUT[1] = {{
H5O_layout_reset, /*reset method */
H5O_layout_free, /*free the struct */
H5O_layout_delete, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_layout_debug, /*debug the message */
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index b1d7496..0f56ee1 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -58,6 +58,7 @@ const H5O_class_t H5O_MTIME[1] = {{
H5O_mtime_reset, /* reset method */
H5O_mtime_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_mtime_debug, /*debug the message */
@@ -76,6 +77,7 @@ const H5O_class_t H5O_MTIME_NEW[1] = {{
H5O_mtime_reset, /* reset method */
H5O_mtime_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_mtime_debug, /*debug the message */
diff --git a/src/H5Oname.c b/src/H5Oname.c
index e6b9fb6..231a177 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -55,6 +55,7 @@ const H5O_class_t H5O_NAME[1] = {{
H5O_name_reset, /*free internal memory */
NULL, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_name_debug, /*debug the message */
diff --git a/src/H5Onull.c b/src/H5Onull.c
index ca811da..bcf3da3 100644
--- a/src/H5Onull.c
+++ b/src/H5Onull.c
@@ -44,6 +44,7 @@ const H5O_class_t H5O_NULL[1] = {{
NULL, /*no reset method */
NULL, /*no free method */
NULL, /*no file delete method */
+ NULL, /*no link method */
NULL, /*no get share method */
NULL, /*no set share method */
NULL, /*no debug method */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 1255764..866e1b7 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -67,6 +67,7 @@ typedef struct H5O_class_t {
herr_t (*reset)(void *); /*free nested data structs */
herr_t (*free)(void *); /*free main data struct */
herr_t (*del)(H5F_t *, hid_t, const void *); /* Delete space in file referenced by this message */
+ herr_t (*link)(H5F_t *, hid_t, const void *); /* Increment any links in file reference by this message */
herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*); /* Get shared information */
herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*); /* Set shared information */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
@@ -195,6 +196,13 @@ H5_DLLVAR const H5O_class_t H5O_MTIME_NEW[1];
H5_DLLVAR const H5O_class_t H5O_PLIST[1];
/* Package-local function prototypes */
+H5_DLL void * H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type,
+ int sequence, void *mesg, hid_t dxpl_id);
+H5_DLL void * H5O_free_real(const H5O_class_t *type, void *mesg);
+
+/* Shared object operators */
+H5_DLL void * H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared,
+ const H5O_class_t *type, void *mesg);
/* Symbol table operators */
H5_DLL void *H5O_stab_fast(const H5G_cache_t *cache, const struct H5O_class_t *type,
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 21e5b11..972e5e0 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -57,6 +57,7 @@ const H5O_class_t H5O_PLINE[1] = {{
H5O_pline_reset, /* reset method */
H5O_pline_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /* get share method */
NULL, /* set share method */
H5O_pline_debug, /* debug the message */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index ed07b24..bcd2e5b 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -208,7 +208,7 @@ H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5G_entry_t *ent/*out*/);
H5_DLL herr_t H5O_open(H5G_entry_t *ent);
H5_DLL herr_t H5O_close(H5G_entry_t *ent);
-H5_DLL int H5O_link(H5G_entry_t *ent, int adjust, hid_t dxpl_id);
+H5_DLL int H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id);
H5_DLL int H5O_count(H5G_entry_t *ent, hid_t type_id, hid_t dxpl_id);
H5_DLL htri_t H5O_exists(H5G_entry_t *ent, hid_t type_id, int sequence,
hid_t dxpl_id);
@@ -232,6 +232,7 @@ H5_DLL herr_t H5O_reset(hid_t type_id, void *native);
H5_DLL void *H5O_free(hid_t type_id, void *mesg);
H5_DLL void *H5O_copy(hid_t type_id, const void *mesg, void *dst);
H5_DLL size_t H5O_raw_size(hid_t type_id, H5F_t *f, const void *mesg);
+H5_DLL herr_t H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share);
H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
H5_DLL 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);
H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 69e3de7..cc24e19 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -47,6 +47,7 @@ const H5O_class_t H5O_SDSPACE[1] = {{
H5O_sdspace_reset, /* default reset method */
H5O_sdspace_free, /* free method */
NULL, /* file delete method */
+ NULL, /* link method */
NULL, /* get share method */
NULL, /* set share method */
H5O_sdspace_debug, /* debug the message */
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index f3f399e..1444e03 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -25,17 +25,22 @@
* the global heap.
*/
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
#include "H5Gprivate.h" /* Groups */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
static void *H5O_shared_decode (H5F_t*, hid_t dxpl_id, const uint8_t*, H5O_shared_t *sh);
static herr_t H5O_shared_encode (H5F_t*, uint8_t*, const void*);
-static size_t H5O_shared_size (H5F_t*, const void*);
+static void *H5O_shared_copy(const void *_mesg, void *_dest);
+static size_t H5O_shared_size (H5F_t*, const void *_mesg);
+static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg);
+static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
static herr_t H5O_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int);
/* This message derives from H5O */
@@ -45,17 +50,22 @@ const H5O_class_t H5O_SHARED[1] = {{
sizeof(H5O_shared_t), /*native message size */
H5O_shared_decode, /*decode method */
H5O_shared_encode, /*encode method */
- NULL, /*no copy method */
+ H5O_shared_copy, /*copy the native value */
H5O_shared_size, /*size method */
NULL, /*no reset method */
NULL, /*no free method */
- NULL, /* file delete method */
+ H5O_shared_delete, /*file delete method */
+ H5O_shared_link, /*link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_shared_debug, /*debug method */
}};
-#define H5O_SHARED_VERSION 1
+/* Old version, with full symbol table entry as link for object header sharing */
+#define H5O_SHARED_VERSION_1 1
+
+/* New version, with just address of object as link for object header sharing */
+#define H5O_SHARED_VERSION 2
/* Interface initialization */
#define PABLO_MASK H5O_shared_mask
@@ -64,6 +74,123 @@ static int interface_initialize_g = 0;
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_read
+ *
+ * Purpose: Reads a message referred to by a shared message.
+ *
+ * Return: Success: Ptr to message in native format. The message
+ * should be freed by calling H5O_reset(). If
+ * MESG is a null pointer then the caller should
+ * also call H5MM_xfree() on the return value
+ * after calling H5O_reset().
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 24 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_class_t *type, void *mesg)
+{
+ void *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_read,NULL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+ assert(type);
+
+ /* Get the shared message */
+ if (shared->in_gh) {
+ void *tmp_buf, *tmp_mesg;
+
+ if (NULL==(tmp_buf = H5HG_read (f, dxpl_id, &(shared->u.gh), NULL)))
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to read shared message from global heap");
+ tmp_mesg = (type->decode)(f, dxpl_id, tmp_buf, shared);
+ tmp_buf = H5MM_xfree (tmp_buf);
+ if (!tmp_mesg)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to decode object header shared message");
+ if (mesg) {
+ HDmemcpy (mesg, tmp_mesg, type->native_size);
+ H5MM_xfree (tmp_mesg);
+ } /* end if */
+ else
+ ret_value = tmp_mesg;
+ } /* end if */
+ else {
+ ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id);
+ if (type->set_share &&
+ (type->set_share)(f, ret_value, shared)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information");
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_shared_link_adj
+ *
+ * Purpose: Changes the link count for the object referenced by a shared
+ * message.
+ *
+ * Return: Success: New link count
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adjust)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_link_adj,FAIL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+
+ if (shared->in_gh) {
+ /*
+ * The shared message is stored in the global heap.
+ * Adjust the reference count on the global heap message.
+ */
+ if ((ret_value = H5HG_link (f, dxpl_id, &(shared->u.gh), adjust))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ } /* end if */
+ else {
+ /*
+ * The shared message is stored in some other object header.
+ * The other object header must be in the same file as the
+ * new object header. Adjust the reference count on that
+ * object header.
+ */
+ if (shared->u.ent.file->shared != f->shared)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
+ if ((ret_value = H5O_link (&(shared->u.ent), adjust, dxpl_id))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_link_adj() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_decode
*
* Purpose: Decodes a shared object message and returns it.
@@ -95,28 +222,36 @@ H5O_shared_decode (H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *buf, H5O_share
assert (!sh);
/* Decode */
- if (NULL==(mesg = H5MM_calloc (sizeof *mesg)))
+ if (NULL==(mesg = H5MM_calloc (sizeof(H5O_shared_t))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Version */
version = *buf++;
- if (version!=H5O_SHARED_VERSION)
+ if (version!=H5O_SHARED_VERSION_1 && version!=H5O_SHARED_VERSION)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for shared object message");
- /* Flags */
+ /* Get the shared information flags */
flags = *buf++;
mesg->in_gh = (flags & 0x01);
- /* Reserved */
- buf += 6;
+ /* Skip reserved bytes (for version 1) */
+ if(version==H5O_SHARED_VERSION_1)
+ buf += 6;
/* Body */
if (mesg->in_gh) {
- H5F_addr_decode (f, &buf, &(mesg->u.gh.addr));
- INT32DECODE (buf, mesg->u.gh.idx);
- } else {
- H5G_ent_decode (f, &buf, &(mesg->u.ent));
- }
+ H5F_addr_decode (f, &buf, &(mesg->u.gh.addr));
+ INT32DECODE (buf, mesg->u.gh.idx);
+ } /* end if */
+ else {
+ if(version==H5O_SHARED_VERSION_1)
+ H5G_ent_decode (f, &buf, &(mesg->u.ent));
+ else {
+ assert(version==H5O_SHARED_VERSION);
+ H5F_addr_decode (f, &buf, &(mesg->u.ent.header));
+ mesg->u.ent.file=f;
+ } /* end else */
+ } /* end else */
/* Set return value */
ret_value=mesg;
@@ -165,6 +300,7 @@ H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg)
*buf++ = H5O_SHARED_VERSION;
flags = mesg->in_gh ? 0x01 : 0x00;
*buf++ = flags;
+#ifdef OLD_WAY
*buf++ = 0; /*reserved 1*/
*buf++ = 0; /*reserved 2*/
*buf++ = 0; /*reserved 3*/
@@ -175,9 +311,17 @@ H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg)
if (mesg->in_gh) {
H5F_addr_encode (f, &buf, mesg->u.gh.addr);
INT32ENCODE (buf, mesg->u.gh.idx);
- } else {
+ } /* end if */
+ else
H5G_ent_encode (f, &buf, &(mesg->u.ent));
- }
+#else /* OLD_WAY */
+ if (mesg->in_gh) {
+ H5F_addr_encode (f, &buf, mesg->u.gh.addr);
+ INT32ENCODE (buf, mesg->u.gh.idx);
+ } /* end if */
+ else
+ H5F_addr_encode (f, &buf, mesg->u.ent.header);
+#endif /* OLD_WAY */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -185,6 +329,49 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_shared_copy(const void *_mesg, void *_dest)
+{
+ const H5O_shared_t *mesg = (const H5O_shared_t *) _mesg;
+ H5O_shared_t *dest = (H5O_shared_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_copy, NULL);
+
+ /* check args */
+ assert(mesg);
+ if (!dest && NULL==(dest = H5MM_malloc (sizeof(H5O_shared_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* copy */
+ *dest = *mesg;
+
+ /* Set return value */
+ ret_value=dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_size
*
* Purpose: Returns the length of a shared object message.
@@ -201,16 +388,18 @@ done:
*-------------------------------------------------------------------------
*/
static size_t
-H5O_shared_size (H5F_t *f, const void UNUSED *_mesg)
+H5O_shared_size (H5F_t *f, const void *_mesg)
{
+ const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
size_t ret_value;
FUNC_ENTER_NOAPI(H5O_shared_size, 0);
- ret_value = 1 + /*the flags field */
- 7 + /*reserved */
- MAX (H5F_SIZEOF_ADDR(f)+4, /*sharing via global heap */
- H5G_SIZEOF_ENTRY(f)); /*sharing by another obj hdr */
+ ret_value = 1 + /*version */
+ 1 + /*the flags field */
+ (shared->in_gh ?
+ (H5F_SIZEOF_ADDR(f)+4) : /*sharing via global heap */
+ H5F_SIZEOF_ADDR(f)); /*sharing by another obj hdr */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -218,6 +407,77 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg)
+{
+ const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_delete, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+
+ /* Decrement the reference count on the shared object */
+ if(H5O_shared_link_adj(f,dxpl_id,shared,-1)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_shared_link
+ *
+ * Purpose: Increment reference count on any objects referenced by
+ * message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg)
+{
+ const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_link, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+
+ /* Decrement the reference count on the shared object */
+ if(H5O_shared_link_adj(f,dxpl_id,shared,1)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_link() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_debug
*
* Purpose: Prints debugging info for the message
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 521ffe3..8b33884 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -59,6 +59,7 @@ const H5O_class_t H5O_STAB[1] = {{
NULL, /*default reset method */
H5O_stab_free, /* free method */
H5O_stab_delete, /* file delete method */
+ NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_stab_debug, /*debug the message */
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index 5582339..38e0e06 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -124,7 +124,7 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id)
H5F_t *file = NULL;
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_commit, FAIL);
+ FUNC_ENTER_NOINIT(H5T_commit);
assert (loc);
assert (name && *name);
@@ -204,9 +204,71 @@ H5Tcommitted(hid_t type_id)
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/* Set return value */
- ret_value= (H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state);
+ ret_value= H5T_committed(type);
done:
FUNC_LEAVE_API(ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_committed
+ *
+ * Purpose: Determines if a data type is committed or not.
+ *
+ * Return: Success: TRUE if committed, FALSE otherwise.
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, September 24, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5T_committed(H5T_t *type)
+{
+ /* Use no-init for efficiency */
+ FUNC_ENTER_NOINIT(H5T_committed);
+
+ assert (type);
+
+ FUNC_LEAVE_NOAPI(H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state);
+} /* end H5T_committed() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_link
+ *
+ * Purpose: Adjust the link count for an object header by adding
+ * ADJUST to the link count.
+ *
+ * Return: Success: New link count
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id)
+{
+ int ret_value; /* Return value */
+
+ /* Use no-init for efficiency */
+ FUNC_ENTER_NOAPI(H5T_link,FAIL);
+
+ assert (type);
+
+ /* Adjust the link count on the named datatype */
+ if((ret_value=H5O_link(&(type->ent),adjust,dxpl_id))<0)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_LINK, FAIL, "unable to adjust named datatype link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5T_link() */
+
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 1897dbf..ce975a1 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -72,6 +72,8 @@ H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id,
H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *_op_data);
H5_DLL htri_t H5T_is_sensible(const H5T_t *dt);
H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
+H5_DLL htri_t H5T_committed(H5T_t *type);
+H5_DLL int H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id);
/* Reference specific functions */
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);