From eed7245d7ca7b3f6478349a4b48e95a0ebdf26d8 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Tue, 21 Apr 2009 09:09:23 -0500 Subject: [svn-r16815] Description: Added member function Attribute::getInMemDataSize(), which is a wrapper of several C calls, 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 to tests in tattr.cpp. Platforms tested: Linux/32 2.6 (jam) FreeBSD/64 6.3 (liberty) SunOS 5.10 (linew) --- c++/src/H5Attribute.cpp | 79 +++++++++++++++++++++++++++++++++++++++++-------- c++/src/H5Attribute.h | 3 ++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp index d80286b..a844b77 100644 --- a/c++/src/H5Attribute.cpp +++ b/c++/src/H5Attribute.cpp @@ -150,6 +150,50 @@ void Attribute::read( const DataType& mem_type, void *buf ) const } //-------------------------------------------------------------------------- +// Function: Attribute::getInMemDataSize +///\brief Gets the size in memory of the attribute's data. +///\exception H5::AttributeIException +// Programmer Binh-Minh Ribler - 2000 +//-------------------------------------------------------------------------- +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. @@ -163,14 +207,8 @@ void Attribute::read( const DataType& mem_type, void *buf ) const // space for the buffer. Obtained the attribute size and // allocated memory properly. - 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 +221,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 +262,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 9cf91ba..00a08a5 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; -- cgit v0.12