summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5A.c202
-rw-r--r--src/H5Aprivate.h6
-rw-r--r--src/H5Apublic.h28
-rw-r--r--src/H5G.c3
-rw-r--r--test/tattr.c131
5 files changed, 338 insertions, 32 deletions
diff --git a/src/H5A.c b/src/H5A.c
index b32572b..24efd72 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -959,7 +959,7 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
/* check arguments */
if (NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute");
- if (!buf || buf_size<1)
+ if (!buf && buf_size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer");
/* get the real attribute length */
@@ -970,10 +970,12 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
copy_len = MIN(buf_size-1, nbytes);
/* Copy all/some of the name */
- HDmemcpy(buf, attr->name, copy_len);
+ if(buf && copy_len>0) {
+ HDmemcpy(buf, attr->name, copy_len);
- /* Terminate the string */
- buf[copy_len]='\0';
+ /* Terminate the string */
+ buf[copy_len]='\0';
+ }
/* Set return value */
ret_value = (ssize_t)nbytes;
@@ -983,6 +985,81 @@ done:
} /* H5Aget_type() */
+/*-------------------------------------------------------------------------
+ * Function: H5Aget_storage_size
+ *
+ * Purpose: Returns the amount of storage size that is required for this
+ * attribute.
+ *
+ * Return: Success: The amount of storage size allocated for the
+ * attribute. The return value may be zero
+ * if no data has been stored.
+ *
+ * Failure: Zero
+ *
+ * Programmer: Raymond Lu
+ * October 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5Aget_storage_size(hid_t attr_id)
+{
+ H5A_t *attr=NULL;
+ hsize_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Aget_storage_size, 0);
+ H5TRACE1("h","i",attr_id);
+
+ /* Check args */
+ if (NULL==(attr=H5I_object_verify(attr_id, H5I_ATTR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute");
+
+ /* Set return value */
+ ret_value = H5A_get_storage_size(attr);
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_get_storage_size
+ *
+ * Purpose: Private function for H5Aget_storage_size. Returns the
+ * amount of storage size that is required for this
+ * attribute.
+ *
+ * Return: Success: The amount of storage size allocated for the
+ * attribute. The return value may be zero
+ * if no data has been stored.
+ *
+ * Failure: Zero
+ *
+ * Programmer: Raymond Lu
+ * October 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5A_get_storage_size(H5A_t *attr)
+{
+ hsize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5A_get_storage_size, 0);
+
+ /* Set return value */
+ ret_value = attr->data_size;
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
/*--------------------------------------------------------------------------
NAME
H5Aget_num_attrs
@@ -1042,6 +1119,121 @@ done:
} /* H5Aget_num_attrs() */
+/*-------------------------------------------------------------------------
+ * Function: H5Arename
+ *
+ * Purpose: Rename an attribute
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * October 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Arename(hid_t loc_id, char *old_name, char *new_name)
+{
+ H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Arename, FAIL);
+ H5TRACE3("e","iss",loc_id,old_name,new_name);
+
+ /* check arguments */
+ if (!old_name || !new_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "name is nil");
+ if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
+ if (NULL==(ent=H5G_loc(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
+
+ /* Call private function */
+ ret_value = H5A_rename(ent, old_name, new_name);
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_rename
+ *
+ * Purpose: Private function for H5Arename. Rename an attribute
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * October 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_rename(H5G_entry_t *ent, char *old_name, char *new_name)
+{
+ int seq, idx=FAIL; /* Index of attribute being querried */
+ H5A_t *found_attr; /* Attribute with OLD_NAME */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5A_rename, FAIL);
+
+ /* Check arguments */
+ assert(ent);
+ assert(old_name);
+ assert(new_name);
+
+ /* Build the attribute information */
+ if((found_attr = HDcalloc(1, sizeof(H5A_t)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info");
+
+ /* Read in the existing attributes to check for duplicates */
+ seq=0;
+ while(H5O_read(ent, H5O_ATTR, seq, found_attr)!=NULL) {
+ /*
+ * Compare found attribute name.
+ */
+ if(HDstrcmp(found_attr->name,old_name)==0) {
+ idx = seq;
+ break;
+ }
+ H5O_reset (H5O_ATTR, found_attr);
+ seq++;
+ }
+
+ if(idx<0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute cannot be found");
+
+ /* Copy the attribute name. */
+ if(found_attr->name)
+ HDfree(found_attr->name);
+ found_attr->name = HDstrdup(new_name);
+ if(!found_attr->name)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "String copy failed");
+
+ /* Indicate entry is not opened and the attribute doesn't need fill-values. */
+ found_attr->ent_opened=FALSE;
+ found_attr->initialized=TRUE;
+
+ /* Modify the attribute message */
+ if (H5O_modify(ent, H5O_ATTR, idx, 0, found_attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages");
+
+ /* Close the attribute */
+ if(found_attr) H5A_close(found_attr);
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
/*--------------------------------------------------------------------------
NAME
H5Aiterate
@@ -1309,7 +1501,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5A_close
*
- * Purpose: Frees a attribute and all associated memory.
+ * Purpose: Frees an attribute and all associated memory.
*
* Return: Non-negative on success/Negative on failure
*
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index d94df90..7f61a12 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -25,8 +25,10 @@ typedef struct H5A_t H5A_t;
/* Private headers needed by this file */
/* Functions defined in H5A.c */
-H5_DLL H5A_t * H5A_copy(const H5A_t *old_attr);
-H5_DLL herr_t H5A_close(H5A_t *attr);
+H5_DLL H5A_t *H5A_copy(const H5A_t *old_attr);
+H5_DLL herr_t H5A_close(H5A_t *attr);
H5_DLL H5G_entry_t *H5A_entof(H5A_t *attr);
+H5_DLL hsize_t H5A_get_storage_size(H5A_t *attr);
+H5_DLL herr_t H5A_rename(H5G_entry_t *ent, char *old_name, char *new_name);
#endif
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index aa7d0eb..218e481 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -27,20 +27,22 @@ typedef herr_t (*H5A_operator_t)(hid_t location_id/*in*/,
const char *attr_name/*in*/, void *operator_data/*in,out*/);
/* Public function prototypes */
-H5_DLL hid_t H5Acreate(hid_t loc_id, const char *name, hid_t type_id,
- hid_t space_id, hid_t plist_id);
-H5_DLL hid_t H5Aopen_name(hid_t loc_id, const char *name);
-H5_DLL hid_t H5Aopen_idx(hid_t loc_id, unsigned idx);
-H5_DLL herr_t H5Awrite(hid_t attr_id, hid_t type_id, const void *buf);
-H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf);
-H5_DLL herr_t H5Aclose(hid_t attr_id);
-H5_DLL hid_t H5Aget_space(hid_t attr_id);
-H5_DLL hid_t H5Aget_type(hid_t attr_id);
+H5_DLL hid_t H5Acreate(hid_t loc_id, const char *name, hid_t type_id,
+ hid_t space_id, hid_t plist_id);
+H5_DLL hid_t H5Aopen_name(hid_t loc_id, const char *name);
+H5_DLL hid_t H5Aopen_idx(hid_t loc_id, unsigned idx);
+H5_DLL herr_t H5Awrite(hid_t attr_id, hid_t type_id, const void *buf);
+H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf);
+H5_DLL herr_t H5Aclose(hid_t attr_id);
+H5_DLL hid_t H5Aget_space(hid_t attr_id);
+H5_DLL hid_t H5Aget_type(hid_t attr_id);
H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf);
-H5_DLL int H5Aget_num_attrs(hid_t loc_id);
-H5_DLL herr_t H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op,
- void *op_data);
-H5_DLL herr_t H5Adelete(hid_t loc_id, const char *name);
+H5_DLL hsize_t H5Aget_storage_size(hid_t attr_id);
+H5_DLL int H5Aget_num_attrs(hid_t loc_id);
+H5_DLL herr_t H5Arename(hid_t loc_id, char *old_name, char *new_name);
+H5_DLL herr_t H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op,
+ void *op_data);
+H5_DLL herr_t H5Adelete(hid_t loc_id, const char *name);
#ifdef __cplusplus
}
diff --git a/src/H5G.c b/src/H5G.c
index f6f0633..d08ac5b 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -2415,7 +2415,8 @@ H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf)
buf[0] = '\0';
ret_value = 0;
} else {
- HDstrncpy(buf, comment.s, bufsize);
+ if(buf && bufsize)
+ HDstrncpy(buf, comment.s, bufsize);
ret_value = (int)HDstrlen(comment.s);
H5O_reset(H5O_NAME, &comment);
}
diff --git a/test/tattr.c b/test/tattr.c
index 43c87dd..f211c5e 100644
--- a/test/tattr.c
+++ b/test/tattr.c
@@ -1,13 +1,13 @@
/****************************************************************************
- * NCSA HDF *
- * Software Development Group *
- * National Center for Supercomputing Applications *
- * University of Illinois at Urbana-Champaign *
- * 605 E. Springfield, Champaign IL 61820 *
- * *
- * For conditions of distribution and use, see the accompanying *
- * hdf/COPYING file. *
- * *
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
****************************************************************************/
/* $Id$ */
@@ -26,6 +26,7 @@
#define FILENAME "tattr.h5"
#define ATTR_NAME_LEN 16
#define ATTR_MAX_DIMS 7
+#define ATTR_TMP_NAME "temp_name"
/* 3-D dataset with fixed dimensions */
#define SPACE1_NAME "Space1"
@@ -43,6 +44,10 @@
#define ATTR1_DIM1 3
int attr_data1[ATTR1_DIM1]={512,-234,98123}; /* Test data for 1st attribute */
+/* rank & dimensions for another attribute */
+#define ATTR1A_NAME "Attr1_a"
+int attr_data1a[ATTR1_DIM1]={256,11945,-22107};
+
#define ATTR2_NAME "Attr2"
#define ATTR2_RANK 2
#define ATTR2_DIM1 2
@@ -92,7 +97,10 @@ test_attr_basic_write(void)
hid_t dataset; /* Dataset ID */
hid_t group; /* Group ID */
hid_t sid1,sid2; /* Dataspace ID */
- hid_t attr; /* Attribute ID */
+ hid_t attr, attr2; /* Attribute ID */
+ hsize_t attr_size; /* storage size for attribute */
+ ssize_t attr_name_size; /* size of attribute name */
+ char *attr_name; /* name of attribute */
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
hsize_t dims2[] = {ATTR1_DIM1};
hsize_t dims3[] = {ATTR2_DIM1,ATTR2_DIM2};
@@ -134,6 +142,18 @@ test_attr_basic_write(void)
ret=H5Awrite(attr,H5T_NATIVE_INT,attr_data1);
CHECK(ret, FAIL, "H5Awrite");
+ /* Create an another attribute for the dataset */
+ attr2=H5Acreate(dataset,ATTR1A_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
+ CHECK(attr, FAIL, "H5Acreate");
+
+ /* Write attribute information */
+ ret=H5Awrite(attr2,H5T_NATIVE_INT,attr_data1a);
+ CHECK(ret, FAIL, "H5Awrite");
+
+ /* Check storage size for attribute */
+ attr_size=H5Aget_storage_size(attr);
+ VERIFY(attr_size, (ATTR1_DIM1*sizeof(int)), "H5A_get_storage_size");
+
/* Read attribute information immediately, without closing attribute */
ret=H5Aread(attr,H5T_NATIVE_INT,read_data1);
CHECK(ret, FAIL, "H5Aread");
@@ -149,6 +169,87 @@ test_attr_basic_write(void)
ret=H5Aclose(attr);
CHECK(ret, FAIL, "H5Aclose");
+ /* Close attribute */
+ ret=H5Aclose(attr2);
+ CHECK(ret, FAIL, "H5Aclose");
+
+ /* change attribute name */
+ ret=H5Arename(dataset, ATTR1_NAME, ATTR_TMP_NAME);
+ CHECK(ret, FAIL, "H5Arename");
+
+ /* Open attribute again */
+ attr=H5Aopen_name(dataset, ATTR_TMP_NAME);
+ CHECK(attr, FAIL, "H5Aopen_name");
+
+ /* Verify new attribute name */
+ attr_name_size = H5Aget_name(attr, 0, NULL);
+ CHECK(attr_name_size, FAIL, "H5Aget_name");
+
+ if(attr_name_size>0)
+ attr_name = (char*)HDcalloc(attr_name_size+1, sizeof(char));
+
+ ret=H5Aget_name(attr, attr_name_size+1, attr_name);
+ CHECK(ret, FAIL, "H5Aget_name");
+ ret=HDstrcmp(attr_name, ATTR_TMP_NAME);
+ VERIFY(ret, 0, "HDstrcmp");
+
+ if(attr_name)
+ HDfree(attr_name);
+
+ /* Read attribute information immediately, without closing attribute */
+ ret=H5Aread(attr,H5T_NATIVE_INT,read_data1);
+ CHECK(ret, FAIL, "H5Aread");
+
+ /* Verify values read in */
+ for(i=0; i<ATTR1_DIM1; i++)
+ if(attr_data1[i]!=read_data1[i]) {
+ printf("2. attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ num_errs++;
+ } /* end if */
+
+ /* Close attribute */
+ ret=H5Aclose(attr);
+ CHECK(ret, FAIL, "H5Aclose");
+
+
+ /* Open the second attribute again */
+ attr2=H5Aopen_name(dataset, ATTR1A_NAME);
+ CHECK(attr, FAIL, "H5Aopen_name");
+
+ /* Verify new attribute name */
+ attr_name_size = H5Aget_name(attr2, 0, NULL);
+ CHECK(attr_name_size, FAIL, "H5Aget_name");
+
+ if(attr_name_size>0)
+ attr_name = (char*)HDcalloc(attr_name_size+1, sizeof(char));
+
+ ret=H5Aget_name(attr2, attr_name_size+1, attr_name);
+ CHECK(ret, FAIL, "H5Aget_name");
+ ret=HDstrcmp(attr_name, ATTR1A_NAME);
+ VERIFY(ret, 0, "HDstrcmp");
+
+ if(attr_name)
+ HDfree(attr_name);
+
+ /* Read attribute information immediately, without closing attribute */
+ ret=H5Aread(attr2,H5T_NATIVE_INT,read_data1);
+ CHECK(ret, FAIL, "H5Aread");
+
+ /* Verify values read in */
+ for(i=0; i<ATTR1_DIM1; i++)
+ if(attr_data1a[i]!=read_data1[i]) {
+ printf("2. attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ num_errs++;
+ } /* end if */
+
+ /* Close attribute */
+ ret=H5Aclose(attr2);
+ CHECK(ret, FAIL, "H5Aclose");
+
+ /* change first attribute back to the original name */
+ ret=H5Arename(dataset, ATTR_TMP_NAME, ATTR1_NAME);
+ CHECK(ret, FAIL, "H5Arename");
+
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");
ret = H5Sclose(sid2);
@@ -170,6 +271,10 @@ test_attr_basic_write(void)
attr=H5Acreate(group,ATTR2_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
CHECK(attr, FAIL, "H5Acreate");
+ /* Check storage size for attribute */
+ attr_size=H5Aget_storage_size(attr);
+ VERIFY(attr_size, (ATTR2_DIM1*ATTR2_DIM2*sizeof(int)), "H5Aget_storage_size");
+
/* Try to create the same attribute again (should fail) */
ret=H5Acreate(group,ATTR2_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
VERIFY(ret, FAIL, "H5Acreate");
@@ -178,6 +283,10 @@ test_attr_basic_write(void)
ret=H5Awrite(attr,H5T_NATIVE_INT,attr_data2);
CHECK(ret, FAIL, "H5Awrite");
+ /* Check storage size for attribute */
+ attr_size=H5Aget_storage_size(attr);
+ VERIFY(attr_size, (ATTR2_DIM1*ATTR2_DIM2*sizeof(int)), "H5A_get_storage_size");
+
/* Close attribute */
ret=H5Aclose(attr);
CHECK(ret, FAIL, "H5Aclose");
@@ -225,7 +334,7 @@ test_attr_basic_read(void)
/* Verify the correct number of attributes */
ret=H5Aget_num_attrs(dataset);
- VERIFY(ret, 1, "H5Aget_num_attrs");
+ VERIFY(ret, 2, "H5Aget_num_attrs");
/* Open an attribute for the dataset */
attr=H5Aopen_name(dataset,ATTR1_NAME);