summaryrefslogtreecommitdiffstats
path: root/src/H5Oattr.c
diff options
context:
space:
mode:
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: