summaryrefslogtreecommitdiffstats
path: root/src/H5Oattr.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-10-05 21:12:26 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-10-05 21:12:26 (GMT)
commitb8201120fc7547b912222f22a41193921a0c003a (patch)
treeb9dc0099e8c7c4d5899216969be95ff20e6d394f /src/H5Oattr.c
parentb6be270f1fc2d8af09b0986e9f792f0af44a4ae6 (diff)
downloadhdf5-b8201120fc7547b912222f22a41193921a0c003a.zip
hdf5-b8201120fc7547b912222f22a41193921a0c003a.tar.gz
hdf5-b8201120fc7547b912222f22a41193921a0c003a.tar.bz2
[svn-r7538] Purpose:
Bug fixes and code cleanup Description: Lots of changes here: - Fixed bug #691 - when shared datatypes are used in attributes they are incorrectly copied into the attribute instead of referring the the named datatype in the file. This required bumping the version of the attribute message. The new version of the attribute message is only written out when a shared datatype is used in the attribute. [Also, this format change made the size of the attribute smaller.] - Added information to attribute debugging routine so that shared datatypes are displayed correctly with the h5debug tool. - Refactored the H5O* routines to extract code that was common to several routines into subroutines to call. - Added 'link' method for H5O message sub-classes, which increments the link count on shared objects when a message is created which shares them. - Corrected [unreported] bug where the link count was not being decremented on the shared object when a object header message with a reference to that object was deleted from the file. - Reduced size of shared message from 49 bytes (which was incorrect anyway and should have been 48 bytes) to 10 bytes, which required bumping the version of "shared" messages. - Refactored some of the shared datatype routines to allow for easier queries of "committedness" internally to the library and also added routine to easily increment/decrement the reference count of a shared datatype. Platforms tested: FreeBSD 4.9 (sleipnir) h5committest
Diffstat (limited to 'src/H5Oattr.c')
-rw-r--r--src/H5Oattr.c296
1 files changed, 254 insertions, 42 deletions
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: