summaryrefslogtreecommitdiffstats
path: root/c++
diff options
context:
space:
mode:
authorBinh-Minh Ribler <bmribler@hdfgroup.org>2009-04-21 20:57:26 (GMT)
committerBinh-Minh Ribler <bmribler@hdfgroup.org>2009-04-21 20:57:26 (GMT)
commit91e9a5d5c8970f754ab8b5a77b0573dc34da4076 (patch)
treec08ccf0bfa91035d1de937e2d82bcba739e82717 /c++
parent40df33dff700188b3550150f1ab5d036c7d8c02d (diff)
downloadhdf5-91e9a5d5c8970f754ab8b5a77b0573dc34da4076.zip
hdf5-91e9a5d5c8970f754ab8b5a77b0573dc34da4076.tar.gz
hdf5-91e9a5d5c8970f754ab8b5a77b0573dc34da4076.tar.bz2
[svn-r16822] Description:
Added member function Attribute::getInMemDataSize() to simplify getting the attribute's data size in memory. Used this new function in Attribute::read to get the fixed-len string attribute data. Added tests to tattr.cpp. Platforms tested: Linux/32 2.6 (jam) FreeBSD/64 6.3 (liberty) SunOS 5.10 (linew)
Diffstat (limited to 'c++')
-rw-r--r--c++/src/H5Attribute.cpp82
-rw-r--r--c++/src/H5Attribute.h3
-rw-r--r--c++/test/tattr.cpp12
3 files changed, 84 insertions, 13 deletions
diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp
index d80286b..5f429d6 100644
--- a/c++/src/H5Attribute.cpp
+++ b/c++/src/H5Attribute.cpp
@@ -150,6 +150,51 @@ void Attribute::read( const DataType& mem_type, void *buf ) const
}
//--------------------------------------------------------------------------
+// Function: Attribute::getInMemDataSize
+///\brief Gets the size in memory of the attribute's data.
+///\return Size of data (in memory)
+///\exception H5::AttributeIException
+// Programmer Binh-Minh Ribler - Apr 2009
+//--------------------------------------------------------------------------
+size_t Attribute::getInMemDataSize() const
+{
+ // Get the data type of this attribute
+ hid_t mem_type_id = H5Aget_type(id);
+ if (mem_type_id <= 0)
+ {
+ throw AttributeIException("Attribute::getDataSize", "H5Aget_type failed");
+ }
+
+ // Get the data type's size
+ hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT);
+ if (native_type < 0)
+ {
+ throw AttributeIException("Attribute::read", "H5Tget_native_type failed");
+ }
+ size_t type_size = H5Tget_size(native_type);
+ if (type_size == 0)
+ {
+ throw AttributeIException("Attribute::read", "H5Tget_size failed");
+ }
+
+ // Get number of elements of the attribute
+ hid_t space_id = H5Aget_space(id);
+ if (space_id < 0)
+ {
+ throw AttributeIException("Attribute::read", "H5Aget_space failed");
+ }
+ hssize_t num_elements = H5Sget_simple_extent_npoints(space_id);
+ if (num_elements < 0)
+ {
+ throw AttributeIException("Attribute::read", "H5Sget_simple_extent_npoints failed");
+ }
+
+ // Calculate and return the size of the data
+ size_t data_size = type_size * num_elements;
+ return(data_size);
+}
+
+//--------------------------------------------------------------------------
// Function: Attribute::read
///\brief This is an overloaded member function, provided for convenience.
/// It reads a \a H5std_string from this attribute.
@@ -162,15 +207,11 @@ void Attribute::read( const DataType& mem_type, void *buf ) const
// Corrected a misunderstanding that H5Aread would allocate
// space for the buffer. Obtained the attribute size and
// allocated memory properly. - BMR
+// Apr 2009
+// Used getInMemDataSize to get attribute data size. - BMR
//--------------------------------------------------------------------------
-void Attribute::read( const DataType& mem_type, H5std_string& strg ) const
+void Attribute::read(const DataType& mem_type, H5std_string& strg) const
{
- // Get the size of the attribute data.
- hsize_t attr_size = H5Aget_storage_size(id);
- if (attr_size <= 0)
- {
- throw AttributeIException("Attribute::read", "Unable to get attribute size before reading");
- }
// Check if this attribute has variable-len string or fixed-len string and
// proceed appropriately.
@@ -183,20 +224,36 @@ void Attribute::read( const DataType& mem_type, H5std_string& strg ) const
// Prepare and call C API to read attribute.
char *strg_C;
herr_t ret_value = 0;
+ size_t attr_size;
if (!is_variable_len) // only allocate for fixed-len string
{
- strg_C = new char [(size_t)attr_size+1];
- if (strg_C == NULL)
+ // Get the size of the attribute's data
+ attr_size = getInMemDataSize();
+
+ if (attr_size > 0)
{
- throw AttributeIException("Attribute::read", "Unable to allocate buffer to read the attribute");
+ strg_C = new char [(size_t)attr_size+1];
+ if (strg_C == NULL)
+ {
+ throw AttributeIException("Attribute::read",
+ "Unable to allocate buffer to read the attribute");
+ }
+ ret_value = H5Aread(id, mem_type.getId(), strg_C);
}
- ret_value = H5Aread(id, mem_type.getId(), strg_C);
+ else
+ HDstrcpy(strg_C, "");
}
else
{
// no allocation for variable-len string; C library will
ret_value = H5Aread(id, mem_type.getId(), &strg_C);
}
+ if( ret_value < 0 )
+ {
+ if (!is_variable_len) // only de-allocate for fixed-len string
+ delete []strg_C;
+ throw AttributeIException("Attribute::read", "H5Aread failed");
+ }
if( ret_value < 0 )
{
@@ -208,7 +265,8 @@ void Attribute::read( const DataType& mem_type, H5std_string& strg ) const
// Get string from the C char* and release resource allocated locally
if (!is_variable_len)
{
- strg_C[attr_size] = '\0';
+ if (strg_C != "")
+ strg_C[attr_size] = '\0';
strg = strg_C;
delete []strg_C;
}
diff --git a/c++/src/H5Attribute.h b/c++/src/H5Attribute.h
index fc411e8..daf60eb 100644
--- a/c++/src/H5Attribute.h
+++ b/c++/src/H5Attribute.h
@@ -40,6 +40,9 @@ class H5_DLLCPP Attribute : public AbstractDs, public IdComponent {
// Returns the amount of storage size required for this attribute.
hsize_t getStorageSize() const;
+ // Returns the in memory size of this attribute's data.
+ size_t getInMemDataSize() const;
+
// Reads data from this attribute.
void read( const DataType& mem_type, void *buf ) const;
void read( const DataType& mem_type, H5std_string& strg ) const;
diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp
index fc39c2b..48a3200 100644
--- a/c++/test/tattr.cpp
+++ b/c++/test/tattr.cpp
@@ -356,7 +356,7 @@ static void test_attr_basic_read()
for(i=0; i<ATTR2_DIM1; i++)
for(j=0; j<ATTR2_DIM2; j++)
if(attr_data2[i][j]!=read_data2[i][j]) {
- TestErrPrintf("%d: attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",__LINE__, i,j,attr_data2[i][j],i,j,read_data1[i]);
+ TestErrPrintf("%d: attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",__LINE__, i,j,attr_data2[i][j],i,j,read_data2[i][j]);
}
PASSED();
} // end try block
@@ -1231,6 +1231,16 @@ static void test_string_attr()
if(HDstrcmp(flstring_att_check, ATTRSTR_DATA.c_str())!=0)
TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,flstring_att_check=%s\n",__LINE__, ATTRSTR_DATA.c_str(), flstring_att_check);
+ // Read and verify the attribute string as a string of chars; buffer
+ // is dynamically allocated.
+ size_t attr_size = gr_flattr1.getInMemDataSize();
+ char *fl_dyn_string_att_check;
+ fl_dyn_string_att_check = new char[attr_size+1];
+ gr_flattr1.read(fls_type, fl_dyn_string_att_check);
+ if(HDstrcmp(fl_dyn_string_att_check, ATTRSTR_DATA.c_str())!=0)
+ TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,flstring_att_check=%s\n",__LINE__, ATTRSTR_DATA.c_str(), fl_dyn_string_att_check);
+ delete []fl_dyn_string_att_check;
+
/* Test Attribute::read(...,H5std_string& strg) with FL string */
// Read and verify the attribute string as an std::string.