summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c++/src/H5Attribute.cpp241
-rw-r--r--c++/src/H5Attribute.h4
-rw-r--r--c++/test/tvlstr.cpp74
3 files changed, 213 insertions, 106 deletions
diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp
index a844b77..b1ab73e 100644
--- a/c++/src/H5Attribute.cpp
+++ b/c++/src/H5Attribute.cpp
@@ -150,50 +150,6 @@ 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.
@@ -206,73 +162,76 @@ size_t Attribute::getInMemDataSize() 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
+// Jul 2009
+// Divided into specific private functions for fixed- and
+// variable-len string data: p_read_fixed_len and
+// p_read_variable_len. This should improve readability.
//--------------------------------------------------------------------------
void Attribute::read(const DataType& mem_type, H5std_string& strg) const
{
-
// Check if this attribute has variable-len string or fixed-len string and
// proceed appropriately.
htri_t is_variable_len = H5Tis_variable_str(mem_type.getId());
if (is_variable_len < 0)
{
- throw AttributeIException("Attribute::write", "H5Tis_variable_str failed");
+ throw AttributeIException("Attribute::read", "H5Tis_variable_str failed");
}
- // 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
+ if (!is_variable_len) // only allocate for fixed-len string
{
- // Get the size of the attribute's data
- attr_size = getInMemDataSize();
-
- if (attr_size > 0)
- {
- 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);
- }
- else
- HDstrcpy(strg_C, "");
+ p_read_fixed_len(mem_type, strg);
}
else
{
- // no allocation for variable-len string; C library will
- ret_value = H5Aread(id, mem_type.getId(), &strg_C);
+ p_read_variable_len(mem_type, strg);
}
- if( ret_value < 0 )
+}
+
+//--------------------------------------------------------------------------
+// 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)
{
- if (!is_variable_len) // only de-allocate for fixed-len string
- delete []strg_C;
- throw AttributeIException("Attribute::read", "H5Aread failed");
+ throw AttributeIException("Attribute::getInMemDataSize", "H5Aget_type failed");
}
- if( ret_value < 0 )
+ // Get the data type's size
+ hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT);
+ if (native_type < 0)
{
- if (!is_variable_len) // only de-allocate for fixed-len string
- delete []strg_C;
- throw AttributeIException("Attribute::read", "H5Aread failed");
+ throw AttributeIException("Attribute::getInMemDataSize", "H5Tget_native_type failed");
+ }
+ size_t type_size = H5Tget_size(native_type);
+ if (type_size == 0)
+ {
+ throw AttributeIException("Attribute::getInMemDataSize", "H5Tget_size failed");
}
- // Get string from the C char* and release resource allocated locally
- if (!is_variable_len)
+ // Get number of elements of the attribute
+ hid_t space_id = H5Aget_space(id);
+ if (space_id < 0)
{
- if (strg_C != "")
- strg_C[attr_size] = '\0';
- strg = strg_C;
- delete []strg_C;
+ throw AttributeIException("Attribute::getInMemDataSize", "H5Aget_space failed");
}
- // Get string from the C char* and release resource allocated by C API
- else
+ hssize_t num_elements = H5Sget_simple_extent_npoints(space_id);
+ if (num_elements < 0)
{
- strg = strg_C;
- HDfree(strg_C);
+ throw AttributeIException("Attribute::getInMemDataSize", "H5Sget_simple_extent_npoints failed");
}
+
+ // Calculate and return the size of the data
+ size_t data_size = type_size * num_elements;
+ return(data_size);
}
//--------------------------------------------------------------------------
@@ -300,26 +259,6 @@ DataSpace Attribute::getSpace() const
}
//--------------------------------------------------------------------------
-// Function: Attribute::p_get_type (private)
-// Purpose Gets the datatype of this attribute.
-// Return Id of the datatype
-// Exception H5::AttributeIException
-// Description
-// This private function is used in AbstractDs.
-// Programmer Binh-Minh Ribler - 2000
-//--------------------------------------------------------------------------
-hid_t Attribute::p_get_type() const
-{
- hid_t type_id = H5Aget_type( id );
- if( type_id > 0 )
- return( type_id );
- else
- {
- throw AttributeIException("", "H5Aget_type failed");
- }
-}
-
-//--------------------------------------------------------------------------
// Function: Attribute::getFileName
///\brief Gets the name of the file, in which this attribute belongs.
///\return File name
@@ -441,6 +380,96 @@ hid_t Attribute::getId() const
}
//--------------------------------------------------------------------------
+// Function: Attribute::p_get_type (private)
+// Purpose Gets the datatype of this attribute.
+// Return Id of the datatype
+// Exception H5::AttributeIException
+// Description
+// This private function is used in AbstractDs.
+// Programmer Binh-Minh Ribler - 2000
+//--------------------------------------------------------------------------
+hid_t Attribute::p_get_type() const
+{
+ hid_t type_id = H5Aget_type( id );
+ if( type_id > 0 )
+ return( type_id );
+ else
+ {
+ throw AttributeIException("", "H5Aget_type failed");
+ }
+}
+
+//--------------------------------------------------------------------------
+// Function: Attribute::p_read_fixed_len (private)
+// brief Reads a fixed length \a H5std_string from an attribute.
+// param mem_type - IN: Attribute datatype (in memory)
+// param strg - IN: Buffer for read string
+// exception H5::AttributeIException
+// Programmer Binh-Minh Ribler - Jul, 2009
+// Modification
+// Jul 2009
+// Separated the fixed length case from the original
+// Attribute::read
+//--------------------------------------------------------------------------
+void Attribute::p_read_fixed_len(const DataType& mem_type, H5std_string& strg) const
+{
+ // Only allocate for fixed-len string.
+
+ // Get the size of the attribute's data
+ size_t attr_size = getInMemDataSize();
+
+ // If there is data, allocate buffer and read it.
+ if (attr_size > 0)
+ {
+ char *strg_C = NULL;
+
+ strg_C = new char [(size_t)attr_size+1];
+ herr_t ret_value = H5Aread(id, mem_type.getId(), strg_C);
+
+ if( ret_value < 0 )
+ {
+ delete []strg_C; // de-allocate for fixed-len string
+ throw AttributeIException("Attribute::read", "H5Aread failed");
+ }
+
+ // Get string from the C char* and release resource allocated locally
+ strg = strg_C;
+ delete []strg_C;
+ }
+}
+
+//--------------------------------------------------------------------------
+// Function: Attribute::p_read_variable_len (private)
+// brief Reads a variable length \a H5std_string from an attribute.
+// param mem_type - IN: Attribute datatype (in memory)
+// param strg - IN: Buffer for read string
+// exception H5::AttributeIException
+// Programmer Binh-Minh Ribler - Jul, 2009
+// Modification
+// Jul 2009
+// Separated the variable length case from the original
+// Attribute::read
+//--------------------------------------------------------------------------
+void Attribute::p_read_variable_len(const DataType& mem_type, H5std_string& strg) const
+{
+
+ // Prepare and call C API to read attribute.
+ char *strg_C;
+
+ // Read attribute, no allocation for variable-len string; C library will
+ herr_t ret_value = H5Aread(id, mem_type.getId(), &strg_C);
+
+ if( ret_value < 0 )
+ {
+ throw AttributeIException("Attribute::read", "H5Aread failed");
+ }
+
+ // Get string from the C char* and release resource allocated by C API
+ strg = strg_C;
+ HDfree(strg_C);
+}
+
+//--------------------------------------------------------------------------
// Function: Attribute::p_setId
///\brief Sets the identifier of this object to a new value.
///
diff --git a/c++/src/H5Attribute.h b/c++/src/H5Attribute.h
index 00a08a5..abece10 100644
--- a/c++/src/H5Attribute.h
+++ b/c++/src/H5Attribute.h
@@ -82,6 +82,10 @@ class H5_DLLCPP Attribute : public AbstractDs, public IdComponent {
// sub-types
virtual hid_t p_get_type() const;
+ // Reads variable or fixed len strings
+ void p_read_variable_len(const DataType& mem_type, H5std_string& strg) const;
+ void p_read_fixed_len(const DataType& mem_type, H5std_string& strg) const;
+
// do not inherit H5Object::iterateAttrs
int iterateAttrs() { return 0; }
diff --git a/c++/test/tvlstr.cpp b/c++/test/tvlstr.cpp
index 2c22903..0abab1b 100644
--- a/c++/test/tvlstr.cpp
+++ b/c++/test/tvlstr.cpp
@@ -670,6 +670,77 @@ static void test_read_vl_string_attribute()
}
} // test_read_vl_string_attribute
+
+/*-------------------------------------------------------------------------
+ * Function: test_vl_stringarray_attribute
+ *
+ * Purpose: Test writing/reading VL string array to/from attributes.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler
+ * July, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+const H5std_string ATTRSTRARR_NAME("StringArray_attr");
+
+static void test_vl_stringarray_attribute()
+{
+ const char *string_att_array[SPACE1_DIM1]= {
+ "Line 1", "Line 2", "Line 3", "Line 4"
+ }; // Information to write
+
+ // Output message about test being performed
+ SUBTEST("Testing writing/reading VL String Array on attribute");
+
+ try {
+ // Open the file
+ H5File file1(FILENAME, H5F_ACC_RDWR);
+
+ // Create a datatype to refer to.
+ StrType tid1(0, H5T_VARIABLE);
+
+ // Open the root group.
+ Group root = file1.openGroup("/");
+
+ // Create dataspace for datasets.
+ hsize_t dims1[] = {SPACE1_DIM1};
+ DataSpace att_space(SPACE1_RANK, dims1);
+
+ // Create an attribute for the root group.
+ Attribute gr_attr = root.createAttribute(ATTRSTRARR_NAME, tid1, att_space);
+
+ // Write data to the attribute.
+ gr_attr.write(tid1, string_att_array);
+
+ // Read and verify the attribute string as a string of chars.
+ // Note: reading by array of H5std_string doesn't work yet.
+ char *string_att_check[SPACE1_DIM1];
+ gr_attr.read(tid1, &string_att_check);
+
+ int ii;
+ for (ii = 0; ii < SPACE1_DIM1; ii++)
+ {
+ if(HDstrcmp(string_att_check[ii], string_att_array[ii])!=0)
+ TestErrPrintf("Line %d: Attribute data different: written=%s,read=%s\n",__LINE__, string_att_check[ii], string_att_check[ii]);
+
+ HDfree(string_att_check[ii]); // note: no need for std::string test
+ }
+
+ // Close group's attribute.
+ gr_attr.close();
+ file1.close();
+
+ PASSED();
+ } // end try block
+
+ // Catch all exceptions.
+ catch (Exception E) {
+ issue_fail_msg("test_string_attr()", __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_vl_stringarray_attribute()
+
/* Helper routine for test_vl_rewrite() */
static void write_scalar_dset(H5File& file, DataType& type, DataSpace& space,
char *name, char *data)
@@ -823,6 +894,9 @@ void test_vlstrings()
test_write_vl_string_attribute();
test_read_vl_string_attribute();
+ // Test using VL string array in attributes
+ test_vl_stringarray_attribute();
+
// Test writing VL datasets in files with lots of unlinking
test_vl_rewrite();