summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBinh-Minh Ribler <bmribler@hdfgroup.org>2014-03-21 23:23:05 (GMT)
committerBinh-Minh Ribler <bmribler@hdfgroup.org>2014-03-21 23:23:05 (GMT)
commit60df159d33d8793dd5764e2ae032e0e89fc44c9b (patch)
tree8a83268f8ee902901d982d33b380568a2962f9ab
parent2e4302818ab260604ffa26e90dab159cf28079d4 (diff)
downloadhdf5-60df159d33d8793dd5764e2ae032e0e89fc44c9b.zip
hdf5-60df159d33d8793dd5764e2ae032e0e89fc44c9b.tar.gz
hdf5-60df159d33d8793dd5764e2ae032e0e89fc44c9b.tar.bz2
[svn-r24865] Description:
- Added another overload for char* argument: ssize_t getComment(const char* name, const size_t buf_size, char* comment) - Changed default value to 0 for the other two getComment methods - Added HDmemset to after every char string allocation to clear the buffer Platforms tested: Linux/ppc64 (ostrich) Linux/32 2.6 (jam) Linux/64 2.6 (platypus)/PGI compilers
-rw-r--r--c++/src/H5CommonFG.cpp9
-rw-r--r--c++/src/H5DataSet.cpp10
-rw-r--r--c++/src/H5EnumType.cpp4
-rw-r--r--c++/src/H5Exception.cpp23
-rw-r--r--c++/src/H5Exception.h7
-rw-r--r--c++/src/H5IdComponent.cpp3
-rw-r--r--c++/src/H5Location.cpp134
-rw-r--r--c++/src/H5Location.h5
-rw-r--r--c++/src/H5PropList.cpp5
-rw-r--r--c++/test/dsets.cpp11
-rw-r--r--c++/test/trefer.cpp6
11 files changed, 156 insertions, 61 deletions
diff --git a/c++/src/H5CommonFG.cpp b/c++/src/H5CommonFG.cpp
index 3bf4b4f..fc8b08d 100644
--- a/c++/src/H5CommonFG.cpp
+++ b/c++/src/H5CommonFG.cpp
@@ -436,6 +436,7 @@ H5std_string CommonFG::getLinkval( const char* name, size_t size ) const
if (val_size > 0)
{
value_C = new char[val_size+1]; // temporary C-string for C API
+ HDmemset(value_C, 0, val_size+1); // clear buffer
ret_value = H5Lget_val(getLocId(), name, value_C, val_size, H5P_DEFAULT);
if( ret_value < 0 )
@@ -881,6 +882,8 @@ H5std_string CommonFG::getObjnameByIdx(hsize_t idx) const
// now, allocate C buffer to get the name
char* name_C = new char[name_len+1];
+ HDmemset(name_C, 0, name_len+1); // clear buffer
+
name_len = H5Lget_name_by_idx(getLocId(), ".", H5_INDEX_NAME, H5_ITER_INC, idx, name_C, name_len+1, H5P_DEFAULT);
// clean up and return the string
@@ -924,8 +927,10 @@ ssize_t CommonFG::getObjnameByIdx(hsize_t idx, char* name, size_t size) const
//--------------------------------------------------------------------------
ssize_t CommonFG::getObjnameByIdx(hsize_t idx, H5std_string& name, size_t size) const
{
- char* name_C = new char[size];
- ssize_t name_len = getObjnameByIdx(idx, name_C, size);
+ char* name_C = new char[size+1]; // temporary C-string for object name
+ HDmemset(name_C, 0, size+1); // clear buffer
+
+ ssize_t name_len = getObjnameByIdx(idx, name_C, size+1);
if(name_len < 0)
throwException("getObjnameByIdx", "H5Lget_name_by_idx failed");
diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp
index 0722ef9..699f982 100644
--- a/c++/src/H5DataSet.cpp
+++ b/c++/src/H5DataSet.cpp
@@ -629,7 +629,7 @@ hid_t DataSet::getId() const
//--------------------------------------------------------------------------
// Function: DataSet::p_read_fixed_len (private)
-// brief Reads a fixed length \a H5std_string from an dataset.
+// brief Reads a fixed length \a H5std_string from a dataset.
// param mem_type - IN: DataSet datatype (in memory)
// param strg - IN: Buffer for read string
// exception H5::DataSetIException
@@ -643,14 +643,14 @@ void DataSet::p_read_fixed_len(const hid_t mem_type_id, const hid_t mem_space_id
// Only allocate for fixed-len string.
// Get the size of the dataset's data
- size_t attr_size = getInMemDataSize();
+ size_t data_size = getInMemDataSize();
// If there is data, allocate buffer and read it.
- if (attr_size > 0)
+ if (data_size > 0)
{
- char *strg_C = NULL;
+ char *strg_C = new char [data_size+1];
+ HDmemset(strg_C, 0, data_size+1); // clear buffer
- strg_C = new char [(size_t)attr_size+1];
herr_t ret_value = H5Dread(id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, strg_C);
if( ret_value < 0 )
diff --git a/c++/src/H5EnumType.cpp b/c++/src/H5EnumType.cpp
index ff632af..04bb9e0 100644
--- a/c++/src/H5EnumType.cpp
+++ b/c++/src/H5EnumType.cpp
@@ -30,6 +30,7 @@
#include "H5AtomType.h"
#include "H5IntType.h"
#include "H5EnumType.h"
+#include "H5private.h" // for HDmemset
#ifndef H5_NO_NAMESPACE
namespace H5 {
@@ -150,6 +151,7 @@ void EnumType::insert( const H5std_string& name, void *value ) const
H5std_string EnumType::nameOf( void *value, size_t size ) const
{
char* name_C = new char[size+1]; // temporary C-string for C API
+ HDmemset(name_C, 0, size+1); // clear buffer
// Calls C routine H5Tenum_nameof to get the name of the specified enum type
herr_t ret_value = H5Tenum_nameof( id, value, name_C, size );
@@ -160,7 +162,7 @@ H5std_string EnumType::nameOf( void *value, size_t size ) const
throw DataTypeIException("EnumType::nameOf", "H5Tenum_nameof failed");
}
// otherwise, create the string to hold the datatype name and return it
- H5std_string name = H5std_string(name_C);
+ H5std_string name(name_C);
delete []name_C;
return( name );
}
diff --git a/c++/src/H5Exception.cpp b/c++/src/H5Exception.cpp
index ddc1d00..492abed 100644
--- a/c++/src/H5Exception.cpp
+++ b/c++/src/H5Exception.cpp
@@ -522,6 +522,29 @@ LibraryIException::LibraryIException(const H5std_string& func_name, const H5std_
LibraryIException::~LibraryIException() throw() {}
//--------------------------------------------------------------------------
+// Subclass: LocationException
+// Programmer Binh-Minh Ribler - 2014
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// Function: LocationException default constructor
+///\brief Default constructor.
+//--------------------------------------------------------------------------
+LocationException::LocationException():Exception(){}
+//--------------------------------------------------------------------------
+// Function: LocationException overloaded constructor
+///\brief Creates a LocationException with the name of the function,
+/// in which the failure occurs, and an optional detailed message.
+///\param func_name - IN: Name of the function where failure occurs
+///\param message - IN: Message on the failure
+//--------------------------------------------------------------------------
+LocationException::LocationException(const H5std_string& func_name, const H5std_string& message) : Exception(func_name, message) {}
+//--------------------------------------------------------------------------
+// Function: LocationException destructor
+///\brief Noop destructor.
+//--------------------------------------------------------------------------
+LocationException::~LocationException() throw() {}
+
+//--------------------------------------------------------------------------
// Subclass: IdComponentException
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
diff --git a/c++/src/H5Exception.h b/c++/src/H5Exception.h
index d747af3..7d71022 100644
--- a/c++/src/H5Exception.h
+++ b/c++/src/H5Exception.h
@@ -155,6 +155,13 @@ class H5_DLLCPP LibraryIException : public Exception {
virtual ~LibraryIException() throw();
};
+class H5_DLLCPP LocationException : public Exception {
+ public:
+ LocationException(const H5std_string& func_name, const H5std_string& message = DEFAULT_MSG);
+ LocationException();
+ virtual ~LocationException() throw();
+};
+
class H5_DLLCPP IdComponentException : public Exception {
public:
IdComponentException(const H5std_string& func_name, const H5std_string& message = DEFAULT_MSG);
diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp
index c60d05c..cdf4272 100644
--- a/c++/src/H5IdComponent.cpp
+++ b/c++/src/H5IdComponent.cpp
@@ -25,6 +25,7 @@
#include "H5Library.h"
#include "H5IdComponent.h"
#include "H5DataSpace.h"
+#include "H5private.h" // for HDmemset
#ifndef H5_NO_NAMESPACE
namespace H5 {
@@ -289,6 +290,8 @@ H5std_string IdComponent::p_get_file_name() const
// Call H5Fget_name again to get the actual file name
char* name_C = new char[name_size+1]; // temporary C-string for C API
+ HDmemset(name_C, 0, name_size+1); // clear buffer
+
name_size = H5Fget_name(temp_id, name_C, name_size+1);
// Check for failure again
diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp
index b413a17..fdbfd61 100644
--- a/c++/src/H5Location.cpp
+++ b/c++/src/H5Location.cpp
@@ -32,6 +32,7 @@
#include "H5File.h"
#include "H5DataSet.h"
#include "H5Attribute.h"
+#include "H5private.h" // for HDmemset
#ifndef H5_NO_NAMESPACE
namespace H5 {
@@ -355,7 +356,7 @@ void H5Location::flush(H5F_scope_t scope) const
herr_t ret_value = H5Fflush(getId(), scope);
if( ret_value < 0 )
{
- throw Exception(inMemFunc("flush"), "H5Fflush failed");
+ throw LocationException(inMemFunc("flush"), "H5Fflush failed");
}
}
@@ -363,7 +364,7 @@ void H5Location::flush(H5F_scope_t scope) const
// Function: H5Location::getFileName
///\brief Gets the name of the file, in which this HDF5 object belongs.
///\return File name
-///\exception H5::IdComponentException
+///\exception H5::LocationException
// Programmer Binh-Minh Ribler - Jul, 2004
//--------------------------------------------------------------------------
H5std_string H5Location::getFileName() const
@@ -371,7 +372,7 @@ H5std_string H5Location::getFileName() const
try {
return(p_get_file_name());
}
- catch (IdComponentException E) {
+ catch (LocationException E) {
throw FileIException(inMemFunc("getFileName"), E.getDetailMsg());
}
}
@@ -381,7 +382,7 @@ H5std_string H5Location::getFileName() const
///\brief Sets or resets the comment for an object specified by its name.
///\param name - IN: Name of the object
///\param comment - IN: New comment
-///\exception H5::Exception
+///\exception H5::LocationException
///\par Description
/// If \a comment is an empty string or a null pointer, the comment
/// message is removed from the object.
@@ -400,7 +401,7 @@ void H5Location::setComment(const char* name, const char* comment) const
{
herr_t ret_value = H5Oset_comment_by_name(getId(), name, comment, H5P_DEFAULT);
if( ret_value < 0 )
- throw Exception(inMemFunc("setComment"), "H5Oset_comment_by_name failed");
+ throw LocationException(inMemFunc("setComment"), "H5Oset_comment_by_name failed");
}
//--------------------------------------------------------------------------
@@ -427,7 +428,7 @@ void H5Location::setComment(const char* comment) const
{
herr_t ret_value = H5Oset_comment_by_name(getId(), ".", comment, H5P_DEFAULT);
if( ret_value < 0 )
- throw Exception(inMemFunc("setComment"), "H5Oset_comment_by_name failed");
+ throw LocationException(inMemFunc("setComment"), "H5Oset_comment_by_name failed");
}
//--------------------------------------------------------------------------
@@ -446,7 +447,7 @@ void H5Location::setComment(const H5std_string& comment) const
// Function: H5Location::removeComment
///\brief Removes the comment from an object specified by its name.
///\param name - IN: Name of the object
-///\exception H5::Exception
+///\exception H5::LocationException
// Programmer Binh-Minh Ribler - May 2005 (moved from CommonFG, Sep 2013)
// 2007: QAK modified to use H5O APIs; however the first parameter is
// no longer just file or group, this function should be moved
@@ -457,7 +458,7 @@ void H5Location::removeComment(const char* name) const
{
herr_t ret_value = H5Oset_comment_by_name(getId(), name, NULL, H5P_DEFAULT);
if( ret_value < 0 )
- throw Exception(inMemFunc("removeComment"), "H5Oset_comment_by_name failed");
+ throw LocationException(inMemFunc("removeComment"), "H5Oset_comment_by_name failed");
}
//--------------------------------------------------------------------------
@@ -474,52 +475,87 @@ void H5Location::removeComment(const H5std_string& name) const
//--------------------------------------------------------------------------
// Function: H5Location::getComment
-///\brief Retrieves comment for the specified object and its comment's
-/// length.
-///\param name - IN: Name of the object
-///\param bufsize - IN: Length of the comment to retrieve
+///\brief Retrieves the comment for this location, returning its length.
+///\param name - IN: Name of the object
+///\param buf_size - IN: Length of the comment to retrieve
+///\param comment - OUT: Retrieved comment
+///\return Actual length of the comment
+///\exception H5::LocationException
+///\par Description
+/// This function retrieves \a buf_size characters of the comment
+/// including the null terminator. Thus, if the actual length
+/// of the comment is more than buf_size-1, the retrieved comment
+/// will be truncated to accommodate the null terminator.
+// Programmer Binh-Minh Ribler - Mar 2014
+//--------------------------------------------------------------------------
+ssize_t H5Location::getComment(const char* name, const size_t buf_size, char* comment) const
+{
+ // H5Oget_comment_by_name will get buf_size chars of the comment including
+ // the null terminator
+ ssize_t comment_len;
+ comment_len = H5Oget_comment_by_name(getId(), name, comment, buf_size, H5P_DEFAULT);
+
+ // If H5Oget_comment_by_name returns a negative value, raise an exception
+ if (comment_len < 0)
+ {
+ throw LocationException("H5Location::getComment", "H5Oget_comment_by_name failed");
+ }
+
+ // Return the comment length, which might be different from buf_size
+ return(comment_len);
+}
+
+//--------------------------------------------------------------------------
+// Function: H5Location::getComment
+///\brief Returns the comment as \a string for this location,
+/// returning its length.
+///\param name - IN: Name of the object
+///\param buf_size - IN: Length of the comment to retrieve, default to 0
///\return Comment string
-///\exception H5::Exception
+///\exception H5::LocationException
// Programmer Binh-Minh Ribler - 2000 (moved from CommonFG, Sep 2013)
-// 2007: QAK modified to use H5O APIs; however the first parameter is
-// no longer just file or group, this function should be moved
-// to another class to accommodate attribute, dataset, and named
-// datatype. - BMR
//--------------------------------------------------------------------------
-H5std_string H5Location::getComment(const char* name, size_t bufsize) const
+H5std_string H5Location::getComment(const char* name, const size_t buf_size) const
{
- // bufsize is default to 256
- // temporary variable
- hid_t loc_id = getId(); // temporary variable
+ // Initialize string to "", so that if there is no comment, the returned
+ // string will be empty
+ H5std_string comment("");
- // temporary C-string for the object's comment; bufsize already including
- // null character
- char* comment_C = new char[bufsize];
- ssize_t ret_value = H5Oget_comment_by_name(loc_id, name, comment_C, bufsize, H5P_DEFAULT);
+ // Preliminary call to get the comment's length
+ ssize_t comment_len = H5Oget_comment_by_name(getId(), name, NULL, (size_t)0, H5P_DEFAULT);
- // if the actual length of the comment is longer than bufsize and bufsize
- // was the default value, i.e., not given by the user, then call
- // H5Oget_comment_by_name again with the correct value.
- // If the call to H5Oget_comment_by_name returned an error, skip this block
- // and throw an exception below.
- if (ret_value >= 0 && (size_t)ret_value > bufsize && bufsize == 256)
- {
- size_t new_size = ret_value;
- delete []comment_C;
- comment_C = new char[new_size]; // new_size including null terminator
- ret_value = H5Oget_comment_by_name(loc_id, name, comment_C, new_size, H5P_DEFAULT);
- }
+ // If H5Oget_comment_by_name returns a negative value, raise an exception
+ if (comment_len < 0)
+ {
+ throw LocationException("H5Location::getComment", "H5Oget_comment_by_name failed");
+ }
- // if H5Oget_comment_by_name returns SUCCEED, return the string comment,
- // otherwise, throw an exception
- if (ret_value < 0) {
- delete []comment_C;
- throw Exception(inMemFunc("getComment"), "H5Oget_comment_by_name failed");
- }
+ // If comment exists, calls C routine again to get it
+ else if (comment_len > 0)
+ {
+ size_t tmp_len = buf_size;
- H5std_string comment = H5std_string(comment_C);
- delete []comment_C;
- return (comment);
+ // If buffer size is not provided, use comment length
+ if (tmp_len == 0)
+ tmp_len = comment_len;
+
+ // Temporary buffer for char* comment
+ char* comment_C = new char[tmp_len+1];
+ HDmemset(comment_C, 0, tmp_len+1); // clear buffer
+
+ // Used overloaded function
+ ssize_t comment_len = getComment(name, tmp_len, comment_C);
+
+ // Convert the C comment to return
+ comment = comment_C;
+
+ // Clean up resource
+ delete []comment_C;
+ }
+ // Otherwise, keep comment intact
+
+ // Return the string comment
+ return(comment);
}
//--------------------------------------------------------------------------
@@ -529,9 +565,9 @@ H5std_string H5Location::getComment(const char* name, size_t bufsize) const
/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000 (moved from CommonFG, Sep 2013)
//--------------------------------------------------------------------------
-H5std_string H5Location::getComment(const H5std_string& name, size_t bufsize) const
+H5std_string H5Location::getComment(const H5std_string& name, const size_t buf_size) const
{
- return(getComment(name.c_str(), bufsize));
+ return(getComment(name.c_str(), buf_size));
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -542,7 +578,7 @@ H5std_string H5Location::getComment(const H5std_string& name, size_t bufsize) co
// name - IN: Name of the object to be referenced
// dataspace - IN: Dataspace with selection
// ref_type - IN: Type of reference; default to \c H5R_DATASET_REGION
-// Exception H5::IdComponentException
+// Exception H5::ReferenceException
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
void H5Location::p_reference(void* ref, const char* name, hid_t space_id, H5R_type_t ref_type) const
diff --git a/c++/src/H5Location.h b/c++/src/H5Location.h
index bbe86fc..11dbf85 100644
--- a/c++/src/H5Location.h
+++ b/c++/src/H5Location.h
@@ -104,8 +104,9 @@ class H5_DLLCPP H5Location : public IdComponent {
void setComment(const H5std_string& comment) const;
// Retrieves comment for the HDF5 object specified by its name.
- H5std_string getComment(const char* name, size_t bufsize=256) const;
- H5std_string getComment(const H5std_string& name, size_t bufsize=256) const;
+ ssize_t getComment(const char* name, const size_t buf_size, char* comment) const;
+ H5std_string getComment(const char* name, size_t buf_size=0) const;
+ H5std_string getComment(const H5std_string& name, size_t buf_size=0) const;
// Removes the comment for the HDF5 object specified by its name.
void removeComment(const char* name) const;
diff --git a/c++/src/H5PropList.cpp b/c++/src/H5PropList.cpp
index 9476d46..a49995d 100644
--- a/c++/src/H5PropList.cpp
+++ b/c++/src/H5PropList.cpp
@@ -390,8 +390,13 @@ void PropList::getProperty(const char* name, void* value) const
//--------------------------------------------------------------------------
H5std_string PropList::getProperty(const char* name) const
{
+ // Get property size first
size_t size = getPropSize(name);
+
+ // Allocate buffer then get the property
char* prop_strg_C = new char[size+1]; // temporary C-string for C API
+ HDmemset(prop_strg_C, 0, size+1); // clear buffer
+
herr_t ret_value = H5Pget(id, name, prop_strg_C); // call C API
// Throw exception if H5Pget returns failure
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
index 811d8c7..b6922c2 100644
--- a/c++/test/dsets.cpp
+++ b/c++/test/dsets.cpp
@@ -120,6 +120,11 @@ test_create( H5File& file)
// way to open an existing dataset for accessing.
dataset = new DataSet (file.openDataSet (DSET_DEFAULT_NAME));
+ // Get and verify the comment from this dataset, using
+ // H5std_string getComment(const H5std_string& name, <buf_size=0, by default>)
+ H5std_string comment = file.getComment(DSET_DEFAULT_NAME);
+ verify_val(comment, "This is a dataset", "H5Location::getComment", __LINE__, __FILE__);
+
// Close the dataset when accessing is completed
delete dataset;
@@ -1067,6 +1072,12 @@ void test_dset()
nerrors += test_multiopen (file)<0 ?1:0;
nerrors += test_types(file)<0 ?1:0;
+ // Get part of the comment, random length using
+ // ssize_t getComment(const char* name, const size_t buf_size, char* comment)
+ char* comment = new char[11];
+ ssize_t comment_len = file.getComment("emit diagnostics", 10, comment);
+ verify_val((const char*)comment, "Causes dia", "H5Location::getComment", __LINE__, __FILE__);
+
// Close group "emit diagnostics".
grp.close();
diff --git a/c++/test/trefer.cpp b/c++/test/trefer.cpp
index 36c2ee4..e7a28de 100644
--- a/c++/test/trefer.cpp
+++ b/c++/test/trefer.cpp
@@ -316,11 +316,13 @@ static void test_reference_obj(void)
// Dereference group object from the location where 'dataset' is located
group.dereference(dataset, &rbuf[2]);
- // Get group's comment
+ // Get group's comment using
+ // H5std_string getComment(const char* name, <buf_size=0 by default>)
H5std_string read_comment1 = group.getComment(".", 10);
verify_val(read_comment1.c_str(), write_comment, "Group::getComment",__LINE__,__FILE__);
- // Test that getComment handles failures gracefully
+ // Test that getComment handles failures gracefully, using
+ // H5std_string getComment(const char* name, <buf_size=0 by default>)
try {
H5std_string read_comment_tmp = group.getComment(NULL);
}