[svn-r24938] Description:

- Overloaded Atribute::getName to take a char* for the attribute name:
        ssize_t Attribute::getName(char* attr_name, size_t buf_size)
    - Switched the arguments in this function:
        ssize_t getName(size_t buf_size, H5std_string& attr_name)
        so it became:
        ssize_t getName(H5std_string& attr_name, size_t buf_size)
        The second argument is default to 0, and can be skipped.
    - Removed this function:
        H5std_string getName(size_t buf_size); it'll collide with the
        first function when that function takes a NULL for the first
        argument, and uses default value for the second argument.
    - Added more tests
Platforms tested:
    Linux/ppc64 (ostrich)
    Linux/32 2.6 (jam)
    SunOS 5.11 (emu)
This commit is contained in:
Binh-Minh Ribler 2014-04-01 00:59:37 -05:00
parent d01ee66666
commit 0fcac56705
4 changed files with 226 additions and 55 deletions

View File

@ -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
///\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( size_t buf_size, H5std_string& attr_name ) const
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.
///\return Name of the attribute
///\param buf_size - IN: Desired length of the name
///\exception H5::AttributeIException
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
H5std_string Attribute::getName( size_t buf_size ) const
{
H5std_string attr_name;
ssize_t name_size = getName( buf_size, attr_name );
return( attr_name );
// let caller catch exception if any
}
//--------------------------------------------------------------------------
// 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.
///\brief Returns the name of this attribute as an \a H5std_string.
///\return Name of the attribute
///\exception H5::AttributeIException
// Programmer Binh-Minh Ribler - May, 2004
// Modification
// Mar 2014 - BMR
// Revised to use the modified getName() above
//--------------------------------------------------------------------------
H5std_string Attribute::getName() 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);
H5std_string attr_name(""); // attribute name to return
H5std_string attr_name;
if (name_size >= 256)
name_size = getName(name_size, attr_name);
// Preliminary call to get the size of the attribute name
ssize_t name_size = H5Aget_name(id, (size_t)0, NULL);
// otherwise, convert the C attribute name and return
else
attr_name = name_C;
// 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
delete []name_C;
return( attr_name );
// 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 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
///\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
//--------------------------------------------------------------------------
ssize_t Attribute::getName(H5std_string& attr_name, size_t len) const
{
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
// Use overloaded function
name_size = getName(name_C, len+1);
// Convert the C attribute name to return
attr_name = name_C;
// Clean up resource
delete []name_C;
}
// Otherwise, keep attr_name intact
// Return name size
return(name_size);
}
//--------------------------------------------------------------------------

View File

@ -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;

View File

@ -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

View File

@ -242,6 +242,123 @@ static void test_attr_basic_write()
}
} // 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