summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c++/src/H5Attribute.cpp148
-rw-r--r--c++/src/H5Attribute.h6
-rw-r--r--c++/src/H5DxferProp.cpp1
-rw-r--r--c++/test/tattr.cpp118
4 files changed, 222 insertions, 51 deletions
diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp
index a98a970..9554f95 100644
--- a/c++/src/H5Attribute.cpp
+++ b/c++/src/H5Attribute.cpp
@@ -299,75 +299,129 @@ H5std_string Attribute::getFileName() const
//--------------------------------------------------------------------------
// Function: Attribute::getName
///\brief Gets the name of this attribute, returning its length.
-///\param buf_size - IN: Desired length of the name
-///\param attr_name - OUT: Buffer for the name string
-///\return Length of the attribute name
+///\param attr_name - OUT: Buffer for the name string as char*
+///\param buf_size - IN: Length of the buffer, default to 0
+///\return Actual length of the attribute name
///\exception H5::AttributeIException
-// Programmer Binh-Minh Ribler - Nov, 2001
-//--------------------------------------------------------------------------
-ssize_t Attribute::getName( size_t buf_size, H5std_string& attr_name ) const
+///\par Description
+/// This function retrieves \a buf_size chars of the attribute's
+/// name including null termination. Thus, if the actual length
+/// of the name is more than buf_size-1, the retrieved name will
+/// be truncated to accommodate the null terminator.
+/// To get length of the attribute's name for buffer allocation,
+/// an application can call this function passing in NULL for the
+/// first argument and ignore the second argument.
+// Programmer Binh-Minh Ribler - Mar, 2014
+//--------------------------------------------------------------------------
+ssize_t Attribute::getName(char* attr_name, size_t buf_size) const
{
- char* name_C = new char[buf_size+1]; // temporary C-string for C API
+ // H5Aget_name will get buf_size-1 chars of the name to null terminate it
+ ssize_t name_size = H5Aget_name(id, buf_size, attr_name);
- // Calls C routine H5Aget_name to get the name of the attribute
- ssize_t name_size = H5Aget_name( id, buf_size, name_C );
+ // If H5Aget_name returns a negative value, raise an exception
+ if (name_size < 0)
+ {
+ throw AttributeIException("Attribute::getName", "H5Aget_name failed");
+ }
+ else if (name_size == 0)
+ {
+ throw AttributeIException("Attribute::getName", "Attribute must have a name, name length is 0");
+ }
- // If H5Aget_name returns a negative value, raise an exception,
- if( name_size < 0 )
- {
- throw AttributeIException("Attribute::getName", "H5Aget_name failed");
- }
- // otherwise, convert the C attribute name and return
- attr_name = name_C;
- delete []name_C;
- return( name_size );
+ return(name_size);
}
//--------------------------------------------------------------------------
// Function: Attribute::getName
-///\brief This is an overloaded member function, provided for convenience.
-/// It differs from the above function in that it returns the
-/// attribute's name, not the length.
+///\brief Returns the name of this attribute as an \a H5std_string.
///\return Name of the attribute
-///\param buf_size - IN: Desired length of the name
///\exception H5::AttributeIException
-// Programmer Binh-Minh Ribler - 2000
+// Programmer Binh-Minh Ribler - May, 2004
+// Modification
+// Mar 2014 - BMR
+// Revised to use the modified getName() above
//--------------------------------------------------------------------------
-H5std_string Attribute::getName( size_t buf_size ) const
+H5std_string Attribute::getName() const
{
- H5std_string attr_name;
- ssize_t name_size = getName( buf_size, attr_name );
- return( attr_name );
- // let caller catch exception if any
+ H5std_string attr_name(""); // attribute name to return
+
+ // Preliminary call to get the size of the attribute name
+ ssize_t name_size = H5Aget_name(id, (size_t)0, NULL);
+
+ // If H5Aget_name failed, throw exception
+ if (name_size < 0)
+ {
+ throw AttributeIException("Attribute::getName", "H5Aget_name failed");
+ }
+ else if (name_size == 0)
+ {
+ throw AttributeIException("Attribute::getName", "Attribute must have a name, name length is 0");
+ }
+ // If attribute's name exists, calls C routine again to get it
+ else if (name_size > 0)
+ {
+ char* name_C = new char[name_size+1]; // temporary C-string
+ HDmemset(name_C, 0, name_size+1); // clear buffer
+
+ // Use overloaded function
+ name_size = getName(name_C, name_size+1);
+
+ // Convert the C attribute name to return
+ attr_name = name_C;
+
+ // Clean up resource
+ delete []name_C;
+
+ }
+ // Return attribute's name
+ return(attr_name);
}
//--------------------------------------------------------------------------
// Function: Attribute::getName
-///\brief This is an overloaded member function, provided for convenience.
-/// It differs from the above functions in that it doesn't take
-/// any arguments and returns the attribute's name.
-///\return Name of the attribute
+///\brief Gets the name of this attribute, returning its length.
+///\param attr_name - OUT: Buffer for the name string as \a H5std_string
+///\param len - IN: Desired length of the name, default to 0
+///\return Actual length of the attribute name
///\exception H5::AttributeIException
-// Programmer Binh-Minh Ribler - May, 2004
+///\par Description
+/// This function retrieves the attribute's name as a string. The
+/// buf_size can specify a specific length or default to 0, in
+/// which case the entire name will be retrieved.
+// Programmer Binh-Minh Ribler - Nov, 2001
+// Modification
+// Mar 2014 - BMR
+// Revised to allow buf_size to be skipped
//--------------------------------------------------------------------------
-H5std_string Attribute::getName() const
+ssize_t Attribute::getName(H5std_string& attr_name, size_t len) const
{
- // Try with 256 characters for the name first, if the name's length
- // returned is more than that then, read the name again with the
- // appropriate space allocation
- char* name_C = new char[256]; // temporary C-string for C API
- ssize_t name_size = H5Aget_name(id, 255, name_C);
+ ssize_t name_size = 0;
+
+ // If no length is provided, get the entire attribute name
+ if (len == 0)
+ {
+ attr_name = getName();
+ name_size = attr_name.length();
+ }
+ // If length is provided, get that number of characters in name
+ else
+ {
+ char* name_C = new char[len+1]; // temporary C-string
+ HDmemset(name_C, 0, len+1); // clear buffer
- H5std_string attr_name;
- if (name_size >= 256)
- name_size = getName(name_size, attr_name);
+ // Use overloaded function
+ name_size = getName(name_C, len+1);
- // otherwise, convert the C attribute name and return
- else
- attr_name = name_C;
+ // Convert the C attribute name to return
+ attr_name = name_C;
+
+ // Clean up resource
+ delete []name_C;
+ }
+ // Otherwise, keep attr_name intact
- delete []name_C;
- return( attr_name );
+ // Return name size
+ return(name_size);
}
//--------------------------------------------------------------------------
diff --git a/c++/src/H5Attribute.h b/c++/src/H5Attribute.h
index 4f15c7f..8332632 100644
--- a/c++/src/H5Attribute.h
+++ b/c++/src/H5Attribute.h
@@ -38,9 +38,9 @@ class H5_DLLCPP Attribute : public AbstractDs, public IdComponent {
H5std_string getFileName() const;
// Gets the name of this attribute.
- ssize_t getName( size_t buf_size, H5std_string& attr_name ) const;
- H5std_string getName( size_t buf_size ) const; // returns name, not its length
- H5std_string getName() const; // returns name, no argument
+ ssize_t getName(char* attr_name, size_t buf_size = 0) const;
+ ssize_t getName(H5std_string& attr_name, size_t buf_size = 0) const;
+ H5std_string getName() const;
// Gets a copy of the dataspace for this attribute.
virtual DataSpace getSpace() const;
diff --git a/c++/src/H5DxferProp.cpp b/c++/src/H5DxferProp.cpp
index 1e5c7b8..c58eeda 100644
--- a/c++/src/H5DxferProp.cpp
+++ b/c++/src/H5DxferProp.cpp
@@ -284,7 +284,6 @@ H5std_string DSetMemXferPropList::getDataTransform() const
{
// Temporary buffer for char* expression
char* exp_C = new char[exp_len+1];
- exp_C = (char *)HDmalloc(exp_len+1);
HDmemset(exp_C, 0, exp_len+1); // clear buffer
// Used overloaded function
diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp
index 7e77e85..e2e347b 100644
--- a/c++/test/tattr.cpp
+++ b/c++/test/tattr.cpp
@@ -244,6 +244,123 @@ static void test_attr_basic_write()
/****************************************************************
**
+** test_attr_getname(): Test getting attribute name functions.
+**
+** Test these functions:
+** A. ssize_t Attribute::getName(char* attr_name, size_t buf_size)
+** 1. With arbitrary buf_size that is larger than the name size
+** 2. With arbitrary buf_size that is smaller than the name's length.
+** 3. With a buf_size that equals the name's length.
+**
+** B. ssize_t Attribute::getName(H5std_string& attr_name, size_t buf_size)
+** With buffer smaller than the actual name
+**
+** C. H5std_string Attribute::getName() with file's and dataset's attrs.
+**
+** D. ssize_t Attribute::getName(H5std_string& attr_name, size_t buf_size)
+** With buffer size equals the name's length, i.e., buf_size=0
+**
+****************************************************************/
+static void test_attr_getname()
+{
+ // Output message about test being performed
+ SUBTEST("Testing all overloads of Attribute::getName");
+
+ try {
+ //
+ // Open the file FILE_BASIC and test getName with its attribute
+ //
+
+ // Open file
+ H5File fid1(FILE_BASIC, H5F_ACC_RDWR);
+
+ // Check for existence of attribute FATTR1_NAME
+ bool attr_exists = fid1.attrExists(FATTR1_NAME);
+ if (attr_exists == false)
+ throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not");
+
+ // Open attribute
+ Attribute fattr1(fid1.openAttribute(FATTR1_NAME));
+
+ // A. Get attribute name with
+ // ssize_t Attribute::getName(char* attr_name, size_t buf_size)
+ // using different buffer sizes and verify against FATTR1_NAME (3 cases)
+
+ // 1. With arbitrary buf_size that is larger than the name size
+ size_t buf_size = FATTR1_NAME.length() + 10;
+ char* fattr1_name = new char[buf_size+1];
+ HDmemset(fattr1_name, 0, buf_size+1);
+ ssize_t name_size = 0; // actual length of attribute name
+ name_size = fattr1.getName(fattr1_name, buf_size+1);
+ verify_val((const char*)fattr1_name, FATTR1_NAME, "Attribute::getName", __LINE__, __FILE__);
+ delete []fattr1_name;
+
+ // 2. With arbitrary buf_size that is smaller than the name's length.
+ // Let's try 4 first characters in the name.
+ buf_size = 4;
+ char short_name[5] = "File"; // to verify the read name
+ fattr1_name = new char[buf_size+1];
+ HDmemset(fattr1_name, 0, buf_size+1);
+ name_size = fattr1.getName(fattr1_name, buf_size+1);
+ verify_val((const char*)fattr1_name, (const char*)short_name, "Attribute::getName", __LINE__, __FILE__);
+ delete []fattr1_name;
+
+ // 3. With a buf_size that equals the name's length.
+ buf_size = FATTR1_NAME.length();
+ fattr1_name = new char[buf_size+1];
+ HDmemset(fattr1_name, 0, buf_size+1);
+ name_size = fattr1.getName(fattr1_name, buf_size+1);
+ verify_val(fattr1_name, FATTR1_NAME, "Attribute::getName", __LINE__, __FILE__);
+ delete []fattr1_name;
+
+ // B. Get attribute name with
+ // ssize_t Attribute::getName(H5std_string& attr_name, size_t buf_size)
+ // using buffer smaller than the actual name
+ buf_size = 4;
+ H5std_string fattr1_name2;
+ name_size = fattr1.getName(fattr1_name2, buf_size);
+
+ // C. Get file attribute's name with
+ // H5std_string Attribute::getName()
+ H5std_string fattr1_name3 = fattr1.getName();
+ verify_val(fattr1_name3, FATTR1_NAME, "Attribute::getName", __LINE__, __FILE__);
+
+ //
+ // Open the dataset DSET1_NAME and test getName with its attribute
+ //
+
+ // Open dataset DSET1_NAME
+ DataSet dataset = fid1.openDataSet(DSET1_NAME);
+
+ // Check for existence of attribute
+ attr_exists = dataset.attrExists(ATTR1_NAME);
+ if (attr_exists == false)
+ throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not");
+
+ // Open attribute
+ Attribute attr1(dataset.openAttribute(ATTR1_NAME));
+
+ // Get dataset attribute's name with
+ // H5std_string Attribute::getName()
+ H5std_string dattr_name1 = attr1.getName();
+ verify_val(dattr_name1, ATTR1_NAME, "Attribute::getName", __LINE__, __FILE__);
+
+ // D. Get attribute name with
+ // H5std_string Attribute::getName(H5std_string attr_name, buf_size=0)
+ H5std_string dattr_name2;
+ name_size = attr1.getName(dattr_name2);
+ verify_val(dattr_name2, ATTR1_NAME, "Attribute::getName", __LINE__, __FILE__);
+
+ PASSED();
+ } // end try block
+
+ catch (Exception E) {
+ issue_fail_msg("test_attr_getname()", __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_attr_getname()
+
+/****************************************************************
+**
** test_attr_rename(): Test renaming attribute function.
**
****************************************************************/
@@ -1433,6 +1550,7 @@ void test_attr()
MESSAGE(5, ("Testing Attributes\n"));
test_attr_basic_write(); // Test basic H5A writing code
+ test_attr_getname(); // Test overloads of Attribute::getName
test_attr_rename(); // Test renaming attribute
test_attr_basic_read(); // Test basic H5A reading code