summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-07-18 02:08:37 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-07-18 02:08:37 (GMT)
commitc55d0f4e1e09e813fec5fcaa0541150c1ee2a36f (patch)
tree9d288066d5140d72c7f27cef72b01274731ab5bd /src
parent2ed54543c8a45e3315d53ba5c1c44e33a98b5c73 (diff)
downloadhdf5-c55d0f4e1e09e813fec5fcaa0541150c1ee2a36f.zip
hdf5-c55d0f4e1e09e813fec5fcaa0541150c1ee2a36f.tar.gz
hdf5-c55d0f4e1e09e813fec5fcaa0541150c1ee2a36f.tar.bz2
[svn-r13988] Description:
Fix bug where the version of an attribute would change after it was created, causing the amount of space used to encode it to change. Tested on: Mac OS X/32 10.4.10 (amazon) FreeBSD/32 6.2 (duty)
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c3
-rw-r--r--src/H5Adense.c3
-rw-r--r--src/H5Aint.c57
-rw-r--r--src/H5Apkg.h23
-rw-r--r--src/H5Oattr.c102
-rw-r--r--src/H5Oattribute.c8
6 files changed, 117 insertions, 79 deletions
diff --git a/src/H5A.c b/src/H5A.c
index b7852ea..c308611 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -398,6 +398,9 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
attr->obj_opened = TRUE;
+ /* Set the version to encode the attribute with */
+ attr->version = H5A_get_version(attr->oloc.file, attr);
+
/* Insert the attribute into the object header */
if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header")
diff --git a/src/H5Adense.c b/src/H5Adense.c
index e35366a..00628b4 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -907,6 +907,9 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
H5MM_xfree(attr_copy->name);
attr_copy->name = H5MM_xstrdup(new_name);
+ /* Recompute the version to encode the attribute with */
+ attr_copy->version = H5A_get_version(f, attr_copy);
+
/* Insert renamed attribute back into dense storage */
/* (Possibly making it shared) */
if(H5A_dense_insert(f, dxpl_id, ainfo, attr_copy) < 0)
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 9dd40ec..f57bd6b 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -669,3 +669,60 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_get_ainfo() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_get_version
+ *
+ * Purpose: Retrieves the correct version to encode attribute with.
+ * Chooses the oldest version possible, unless the "use the
+ * latest format" flag is set.
+ *
+ * Return: Success: Version to encode attribute with.
+ * Failure: Can't fail
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jul 17 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5A_get_version(const H5F_t *f, const H5A_t *attr)
+{
+ hbool_t type_shared, space_shared; /* Flags to indicate that shared messages are used for this attribute */
+ hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
+ unsigned ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5A_get_version)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(attr);
+
+ /* Get the file's 'use the latest version of the format' flag */
+ use_latest_format = H5F_USE_LATEST_FORMAT(f);
+
+ /* Check whether datatype and dataspace are shared */
+ if(H5O_msg_is_shared(H5O_DTYPE_ID, attr->dt) > 0)
+ type_shared = TRUE;
+ else
+ type_shared = FALSE;
+
+ if(H5O_msg_is_shared(H5O_SDSPACE_ID, attr->ds) > 0)
+ space_shared = TRUE;
+ else
+ space_shared = FALSE;
+
+ /* Check which version to encode attribute with */
+ if(use_latest_format)
+ ret_value = H5O_ATTR_VERSION_LATEST; /* Write out latest version of format */
+ else if(attr->encoding != H5T_CSET_ASCII)
+ ret_value = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */
+ else if(type_shared || space_shared)
+ ret_value = H5O_ATTR_VERSION_2; /* Write out version with flag for indicating shared datatype or dataspace */
+ else
+ ret_value = H5O_ATTR_VERSION_1; /* Write out basic version */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_get_version() */
+
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 10cebee..d1cc34c 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -51,6 +51,23 @@
/* Package Private Macros */
/**************************/
+/* This is the initial version, which does not have support for shared datatypes */
+#define H5O_ATTR_VERSION_1 1
+
+/* This version allows support for shared datatypes & dataspaces by adding a
+ * 'flag' byte indicating when those components are shared. This version
+ * also dropped the alignment on all the components.
+ */
+#define H5O_ATTR_VERSION_2 2
+
+/* Add support for different character encodings of attribute names */
+#define H5O_ATTR_VERSION_3 3
+
+/* The latest version of the format. Look through the 'encode', 'decode'
+ * and 'size' message callbacks for places to change when updating this.
+ */
+#define H5O_ATTR_VERSION_LATEST H5O_ATTR_VERSION_3
+
/****************************/
/* Package Private Typedefs */
@@ -60,16 +77,21 @@
struct H5A_t {
H5O_shared_t sh_loc; /* Shared message info (must be first) */
+ unsigned version; /* Version to encode attribute with */
hbool_t initialized;/* Indicate whether the attribute has been modified */
hbool_t obj_opened; /* Object header entry opened? */
H5O_loc_t oloc; /* Object location for object attribute is on */
H5G_name_t path; /* Group hierarchy path */
+
char *name; /* Attribute's name */
H5T_cset_t encoding; /* Character encoding of attribute name */
+
H5T_t *dt; /* Attribute's datatype */
size_t dt_size; /* Size of datatype on disk */
+
H5S_t *ds; /* Attribute's dataspace */
size_t ds_size; /* Size of dataspace on disk */
+
void *data; /* Attribute data (on a temporary basis) */
size_t data_size; /* Size of data on disk */
H5O_msg_crt_idx_t crt_idx; /* Attribute's creation index in the object header */
@@ -186,6 +208,7 @@ H5_DLL herr_t H5A_free(H5A_t *attr);
H5_DLL herr_t H5A_close(H5A_t *attr);
H5_DLL H5O_ainfo_t *H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5O_ainfo_t *ainfo);
+H5_DLL unsigned H5A_get_version(const H5F_t *f, const H5A_t *attr);
/* Attribute "dense" storage routines */
H5_DLL herr_t H5A_dense_create(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo);
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 476721b..b1e5ed3 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -91,21 +91,6 @@ const H5O_msg_class_t H5O_MSG_ATTR[1] = {{
H5O_attr_shared_debug /* debug the message */
}};
-/* This is the initial version, which does not have support for shared datatypes */
-#define H5O_ATTR_VERSION_1 1
-
-/* This version allows support for shared datatypes & dataspaces by adding a
- * 'flag' byte indicating when those components are shared. This version
- * also dropped the alignment on all the components */
-#define H5O_ATTR_VERSION_2 2
-
-/* Add support for different character encodings of attribute names */
-#define H5O_ATTR_VERSION_3 3
-
-/* The latest version of the format. Look through the 'encode', 'decode'
- * and 'size' callback for places to change when updating this. */
-#define H5O_ATTR_VERSION_LATEST H5O_ATTR_VERSION_3
-
/* Flags for attribute flag encoding */
#define H5O_ATTR_FLAG_TYPE_SHARED 0x01
#define H5O_ATTR_FLAG_SPACE_SHARED 0x02
@@ -144,7 +129,6 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
H5A_t *attr = NULL;
H5S_extent_t *extent; /*extent 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 */
@@ -158,12 +142,12 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Version number */
- version = *p++;
- if(version < H5O_ATTR_VERSION_1 || version > H5O_ATTR_VERSION_LATEST)
+ attr->version = *p++;
+ if(attr->version < H5O_ATTR_VERSION_1 || attr->version > H5O_ATTR_VERSION_LATEST)
HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "bad version number for attribute message")
/* Get the flags byte if we have a later version of the attribute */
- if(version >= H5O_ATTR_VERSION_2) {
+ if(attr->version >= H5O_ATTR_VERSION_2) {
flags = *p++;
/* Check for unknown flag */
@@ -185,13 +169,13 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
* Decode the character encoding for the name for versions 3 or later,
* as well as some reserved bytes.
*/
- if(version >= H5O_ATTR_VERSION_3)
+ if(attr->version >= H5O_ATTR_VERSION_3)
attr->encoding = *p++;
/* Decode and store the name */
if(NULL == (attr->name = H5MM_strdup((const char *)p)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- if(version < H5O_ATTR_VERSION_2)
+ if(attr->version < H5O_ATTR_VERSION_2)
p += H5O_ALIGN_OLD(name_len); /* advance the memory pointer */
else
p += name_len; /* advance the memory pointer */
@@ -199,12 +183,12 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
/* Decode the attribute's datatype */
if((attr->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype")
- if(version < H5O_ATTR_VERSION_2)
+ if(attr->version < H5O_ATTR_VERSION_2)
p += H5O_ALIGN_OLD(attr->dt_size);
else
p += attr->dt_size;
- /* decode the attribute dataspace. It can be shared in versions >= 4
+ /* decode the attribute dataspace. It can be shared in versions >= 3
* What's actually shared, though, is only the extent.
*/
if(NULL == (attr->ds = H5FL_CALLOC(H5S_t)))
@@ -224,7 +208,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
if(H5S_select_all(attr->ds, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
- if(version < H5O_ATTR_VERSION_2)
+ if(attr->version < H5O_ATTR_VERSION_2)
p += H5O_ALIGN_OLD(attr->ds_size);
else
p += attr->ds_size;
@@ -271,10 +255,8 @@ 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 */
- unsigned version; /* Attribute version */
htri_t is_type_shared; /* Flag to indicate that a shared datatype is used for this attribute */
htri_t is_space_shared; /* Flag to indicate that a shared dataspace is used for this attribute */
- hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
unsigned flags = 0; /* Attribute flags */
herr_t ret_value = SUCCEED; /* Return value */
@@ -285,9 +267,6 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
HDassert(p);
HDassert(attr);
- /* Get the file's 'use the latest version of the format' flag */
- use_latest_format = H5F_USE_LATEST_FORMAT(f);
-
/* Check whether datatype and dataspace are shared */
if((is_type_shared = H5O_msg_is_shared(H5O_DTYPE_ID, attr->dt)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't determine if datatype is shared")
@@ -295,21 +274,11 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
if((is_space_shared = H5O_msg_is_shared(H5O_SDSPACE_ID, attr->ds)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't determine if dataspace is shared")
- /* Check which version to write out */
- if(use_latest_format)
- version = H5O_ATTR_VERSION_LATEST; /* Write out latest version of format */
- else if(attr->encoding != H5T_CSET_ASCII)
- version = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */
- else if(is_type_shared || is_space_shared)
- version = H5O_ATTR_VERSION_2; /* Write out version with flag for shared datatype & dataspaces */
- else
- version = H5O_ATTR_VERSION_1; /* Write out basic version */
-
/* Encode Version */
- *p++ = version;
+ *p++ = attr->version;
/* Set attribute flags if version >1 */
- if(version >= H5O_ATTR_VERSION_2) {
+ if(attr->version >= H5O_ATTR_VERSION_2) {
flags = (is_type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 );
flags |= (is_space_shared ? H5O_ATTR_FLAG_SPACE_SHARED : 0);
*p++ = flags; /* Set flags for attribute */
@@ -328,12 +297,12 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
UINT16ENCODE(p, attr->ds_size);
/* The character encoding for the attribute's name, in later versions */
- if(version >= H5O_ATTR_VERSION_3)
+ if(attr->version >= H5O_ATTR_VERSION_3)
*p++ = attr->encoding;
/* Write the name including null terminator */
HDmemcpy(p, attr->name, name_len);
- if(version < H5O_ATTR_VERSION_2) {
+ if(attr->version < H5O_ATTR_VERSION_2) {
/* Pad to the correct number of bytes */
HDmemset(p + name_len, 0, H5O_ALIGN_OLD(name_len) - name_len);
p += H5O_ALIGN_OLD(name_len);
@@ -345,7 +314,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
if((H5O_MSG_DTYPE->encode)(f, FALSE, p, attr->dt) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype")
- if(version < H5O_ATTR_VERSION_2) {
+ if(attr->version < H5O_ATTR_VERSION_2) {
HDmemset(p + attr->dt_size, 0, H5O_ALIGN_OLD(attr->dt_size) - attr->dt_size);
p += H5O_ALIGN_OLD(attr->dt_size);
} /* end if */
@@ -356,7 +325,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
if((H5O_MSG_SDSPACE->encode)(f, FALSE, p, &(attr->ds->extent)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace")
- if(version < H5O_ATTR_VERSION_2) {
+ if(attr->version < H5O_ATTR_VERSION_2) {
HDmemset(p + attr->ds_size, 0, H5O_ALIGN_OLD(attr->ds_size) - attr->ds_size);
p += H5O_ALIGN_OLD(attr->ds_size);
} /* end if */
@@ -425,45 +394,16 @@ done:
portion of the message). It doesn't take into account alignment.
--------------------------------------------------------------------------*/
static size_t
-H5O_attr_size(const H5F_t *f, const void *_mesg)
+H5O_attr_size(const H5F_t UNUSED *f, const void *_mesg)
{
const H5A_t *attr = (const H5A_t *)_mesg;
size_t name_len;
- unsigned version; /* Attribute version */
- hbool_t type_shared, space_shared; /* Flags to indicate that shared messages are used for this attribute */
- hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
size_t ret_value = 0;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_size)
HDassert(attr);
- name_len = HDstrlen(attr->name) + 1;
-
- /* Get the file's 'use the latest version of the format' flag */
- use_latest_format = H5F_USE_LATEST_FORMAT(f);
-
- /* Check whether datatype and dataspace are shared */
- if(H5O_msg_is_shared(H5O_DTYPE_ID, attr->dt) > 0)
- type_shared = TRUE;
- else
- type_shared = FALSE;
-
- if(H5O_msg_is_shared(H5O_SDSPACE_ID, attr->ds) > 0)
- space_shared = TRUE;
- else
- space_shared = FALSE;
-
- /* Check which version to write out */
- if(use_latest_format)
- version = H5O_ATTR_VERSION_LATEST; /* Write out latest version of format */
- else if(attr->encoding != H5T_CSET_ASCII)
- version = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */
- else if(type_shared || space_shared)
- version = H5O_ATTR_VERSION_2; /* Write out version with flag for indicating shared datatype or dataspace */
- else
- version = H5O_ATTR_VERSION_1; /* Write out basic version */
-
/* Common size information */
ret_value = 1 + /*version */
1 + /*reserved/flags */
@@ -471,18 +411,21 @@ H5O_attr_size(const H5F_t *f, const void *_mesg)
2 + /*type size */
2; /*space size */
+ /* Length of attribute name */
+ name_len = HDstrlen(attr->name) + 1;
+
/* Version-specific size information */
- if(version == H5O_ATTR_VERSION_1)
+ if(attr->version == H5O_ATTR_VERSION_1)
ret_value += H5O_ALIGN_OLD(name_len) + /*attribute name */
H5O_ALIGN_OLD(attr->dt_size) + /*datatype */
H5O_ALIGN_OLD(attr->ds_size) + /*dataspace */
attr->data_size; /*the data itself */
- else if(version == H5O_ATTR_VERSION_2)
+ else if(attr->version == H5O_ATTR_VERSION_2)
ret_value += name_len + /*attribute name */
attr->dt_size + /*datatype */
attr->ds_size + /*dataspace */
attr->data_size; /*the data itself */
- else if(version == H5O_ATTR_VERSION_3)
+ else if(attr->version == H5O_ATTR_VERSION_3)
ret_value += 1 + /*character encoding */
name_len + /*attribute name */
attr->dt_size + /*datatype */
@@ -889,6 +832,9 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
} /* end else */
} /* end if(attr_src->data) */
+ /* Recompute the version to encode the destination attribute */
+ attr_dst->version = H5A_get_version(file_dst, attr_dst);
+
/* Indicate that the fill values aren't to be written out */
attr_dst->initialized = TRUE;
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index b328f5b..2564386 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -878,10 +878,15 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
/* Find correct attribute message to rename */
if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->old_name) == 0) {
+ unsigned old_version = ((H5A_t *)mesg->native)->version; /* Old version of the attribute */
+
/* Change the name for the attribute */
H5MM_xfree(((H5A_t *)mesg->native)->name);
((H5A_t *)mesg->native)->name = H5MM_xstrdup(udata->new_name);
+ /* Recompute the version to encode the attribute with */
+ ((H5A_t *)mesg->native)->version = H5A_get_version(udata->f, ((H5A_t *)mesg->native));
+
/* Mark message as dirty */
mesg->dirty = TRUE;
@@ -896,7 +901,8 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(H5O_msg_is_shared(H5O_ATTR_ID, (H5A_t *)mesg->native) == FALSE);
/* Check for attribute message changing size */
- if(HDstrlen(udata->new_name) != HDstrlen(udata->old_name)) {
+ if(HDstrlen(udata->new_name) != HDstrlen(udata->old_name) ||
+ old_version != ((H5A_t *)mesg->native)->version) {
H5A_t *attr; /* Attribute to re-add */
/* Take ownership of the message's native info (the attribute)