From c036aa157516f80a14918904673e0d380041a821 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Sun, 24 Apr 2016 15:30:27 -0500 Subject: [svn-r29784] Purpose: Code improvement Description: - Removed ArrayType::rank and ArrayType::dimensions and modified the methods ArrayType::getArrayNDims and ArrayType::getArrayDims to always call the C functions to get the rank and dimensions. - Overloaded ArrayType::getArrayNDims and ArrayType::getArrayDims to provide const version and marked the non-const version deprecated. Merged from trunk r29782. Platforms tested: Linux/32 2.6 (jam) Linux/64 (platypus) Darwin (osx1010test) --- c++/src/H5AbstractDs.cpp | 1 - c++/src/H5ArrayType.cpp | 148 ++++++++++++++++------------------------------- c++/src/H5ArrayType.h | 13 ++--- c++/src/H5CompType.cpp | 3 +- c++/test/tarray.cpp | 127 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 181 insertions(+), 111 deletions(-) diff --git a/c++/src/H5AbstractDs.cpp b/c++/src/H5AbstractDs.cpp index 6dee337..51d5f88 100644 --- a/c++/src/H5AbstractDs.cpp +++ b/c++/src/H5AbstractDs.cpp @@ -145,7 +145,6 @@ ArrayType AbstractDs::getArrayType() const // problem described in the JIRA issue HDFFV-7947 ArrayType arraytype; f_DataType_setId(&arraytype, p_get_type()); - arraytype.setArrayInfo(); return(arraytype); } catch (DataSetIException& E) { diff --git a/c++/src/H5ArrayType.cpp b/c++/src/H5ArrayType.cpp index 37cd8c1..e11227a 100644 --- a/c++/src/H5ArrayType.cpp +++ b/c++/src/H5ArrayType.cpp @@ -35,7 +35,7 @@ namespace H5 { ///\brief Default constructor: Creates a stub ArrayType // Programmer Binh-Minh Ribler - May 2004 //-------------------------------------------------------------------------- -ArrayType::ArrayType() : DataType(), rank(-1), dimensions(NULL) {} +ArrayType::ArrayType() : DataType() {} //-------------------------------------------------------------------------- // Function: ArrayType overloaded constructor @@ -44,23 +44,14 @@ ArrayType::ArrayType() : DataType(), rank(-1), dimensions(NULL) {} ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - May 2004 //-------------------------------------------------------------------------- -ArrayType::ArrayType( const hid_t existing_id ) : DataType( existing_id ) -{ - setArrayInfo(); -} +ArrayType::ArrayType( const hid_t existing_id ) : DataType( existing_id ) {} //-------------------------------------------------------------------------- // Function: ArrayType copy constructor ///\brief Copy constructor: makes a copy of the original ArrayType object. // Programmer Binh-Minh Ribler - May 2004 //-------------------------------------------------------------------------- -ArrayType::ArrayType( const ArrayType& original ) : DataType( original ), rank(original.rank) -{ - // Allocate space then copy the dimensions from the original array - dimensions = new hsize_t[rank]; - for (int i = 0; i < rank; i++) - dimensions[i] = original.dimensions[i]; -} +ArrayType::ArrayType(const ArrayType& original) : DataType(original) {} //-------------------------------------------------------------------------- // Function: ArrayType overloaded constructor @@ -79,14 +70,8 @@ ArrayType::ArrayType(const DataType& base_type, int ndims, const hsize_t* dims) if (new_type_id < 0) throw DataTypeIException("ArrayType constructor", "H5Tarray_create2 failed"); - // Set the id and rank for this object + // Set the id for this object id = new_type_id; - rank = ndims; - - // Allocate space then set the dimensions as provided by caller - dimensions = new hsize_t[rank]; - for (int i = 0; i < rank; i++) - dimensions[i] = dims[i]; } //-------------------------------------------------------------------------- @@ -115,26 +100,21 @@ ArrayType& ArrayType::operator=(const ArrayType& rhs) catch (Exception& close_error) { throw DataTypeIException(inMemFunc("operator="), close_error.getDetailMsg()); } - - // Copy the rank of the rhs array - rank = rhs.rank; - - // Allocate space then copy the dimensions from the rhs array - dimensions = new hsize_t[rank]; - for (int i = 0; i < rank; i++) - dimensions[i] = rhs.dimensions[i]; } return(*this); } //-------------------------------------------------------------------------- -// Function: ArrayType::setArrayInfo -///\brief Retrieves the rank and dimensions from the array datatype -/// and store the info in this ArrayType object. +// Function: ArrayType::getArrayNDims +///\brief Returns the number of dimensions for an array datatype. +///\return Number of dimensions ///\exception H5::DataTypeIException -// Programmer Binh-Minh Ribler - January 2016 +// Programmer Binh-Minh Ribler - May 2004 +// Modification +// Apr, 2016 +// Became const. //-------------------------------------------------------------------------- -void ArrayType::setArrayInfo() +int ArrayType::getArrayNDims() const { // Get the rank of the array type specified by id from the C API int ndims = H5Tget_array_ndims(id); @@ -143,52 +123,24 @@ void ArrayType::setArrayInfo() throw DataTypeIException("ArrayType::setArrayInfo", "H5Tget_array_ndims failed"); } - // Get the dimensions from the C API - hsize_t* dims; - dims = new hsize_t[ndims]; - if (dims != NULL) - { - // Get the dimensions - ndims = H5Tget_array_dims2(id, dims); - if (ndims < 0) - throw DataTypeIException("ArrayType::setArrayInfo", "H5Tget_array_dims2 failed"); - - // Store the array's info in memory - rank = ndims; - dimensions = new hsize_t[rank]; - for (int i = 0; i < rank; i++) - dimensions[i] = dims[i]; - delete []dims; - } -} // setArrayInfo - -//-------------------------------------------------------------------------- + return(ndims); +} +//---------------------------- Deprecated ---------------------------------- // Function: ArrayType::getArrayNDims -///\brief Returns the number of dimensions for an array datatype. -///\return Number of dimensions -///\exception H5::DataTypeIException -// Programmer Binh-Minh Ribler - May 2004 -// Modification -// Modified to use setArrayInfo(). -// If rank is positive, return rank -// If rank is invalid but object has a valid identifier, obtain the -// rank and dimensions, store them in the object, and return rank -// Otherwise, i.e., rank is invalid and object doesn't have a -// valid identifier, throw an exception +// This non-const version of the above method is here for compatibility +// purposes and may be removed in the future. +// -BMR, Apr 2016 //-------------------------------------------------------------------------- int ArrayType::getArrayNDims() { - // Validate the id first, this object could be a default object - if (!p_valid_id(id)) - throw DataTypeIException("ArrayType::getArrayNDims", "ArrayType object is not a valid array type."); - - // If the array's info has not been stored, i.e. "rank" still has its - // initial value, -1, and "dimensions" is still NULL, retrieve rank and - // dimensions via the C API and store them in this ArrayType object. - if (rank < 0 && dimensions == NULL) - setArrayInfo(); + // Get the rank of the array type specified by id from the C API + int ndims = H5Tget_array_ndims(id); + if (ndims < 0) + { + throw DataTypeIException("ArrayType::setArrayInfo", "H5Tget_array_ndims failed"); + } - return(rank); + return(ndims); } //-------------------------------------------------------------------------- @@ -199,29 +151,34 @@ int ArrayType::getArrayNDims() ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - May 2004 // Modification -// Jan, 2016 -// Modified to use setArrayInfo(). -// If the array information has not been stored, retrieve rank and -// dimensions of the array type identified by "id" via the C API. -// Copy "dimensions" to the user's buffer +// Apr, 2016 +// Became const. //-------------------------------------------------------------------------- -int ArrayType::getArrayDims(hsize_t* dims) +int ArrayType::getArrayDims(hsize_t* dims) const { - // Validate the id first, this object could be a default object - if (!p_valid_id(id)) - throw DataTypeIException("ArrayType::getArrayDims", "ArrayType object is not a valid array type."); - - // If the array's info has not been stored, i.e. "rank" still has its - // initial value, -1, and "dimensions" is still NULL, retrieve rank and - // dimensions via the C API and store them in this ArrayType object. - if (rank < 0 && dimensions == NULL) - setArrayInfo(); + // Get the dimensions + int ndims = H5Tget_array_dims2(id, dims); + if (ndims < 0) + throw DataTypeIException("ArrayType::setArrayInfo", "H5Tget_array_dims2 failed"); - // Copy what's in "dimensions" to user's buffer "dims" - for (int i = 0; i < rank; i++) - dims[i] = dimensions[i]; + // Return the number of dimensions + return(ndims); +} +//---------------------------- Deprecated ---------------------------------- +// Function: ArrayType::getArrayDims +// This non-const version of the above method is here for compatibility +// purposes and may be removed in the future. +// -BMR, Apr 2016 +//-------------------------------------------------------------------------- +int ArrayType::getArrayDims(hsize_t* dims) +{ + // Get the dimensions + int ndims = H5Tget_array_dims2(id, dims); + if (ndims < 0) + throw DataTypeIException("ArrayType::setArrayInfo", "H5Tget_array_dims2 failed"); - return(rank); + // Return the number of dimensions + return(ndims); } //-------------------------------------------------------------------------- @@ -229,12 +186,7 @@ int ArrayType::getArrayDims(hsize_t* dims) ///\brief Properly terminates access to this array datatype. // Programmer Binh-Minh Ribler - May 2004 //-------------------------------------------------------------------------- -ArrayType::~ArrayType() -{ - // Free allocated memory - if (dimensions != NULL) - delete []dimensions; -} +ArrayType::~ArrayType() {} #ifndef H5_NO_NAMESPACE } // end namespace diff --git a/c++/src/H5ArrayType.h b/c++/src/H5ArrayType.h index ddbb5e2..eee430e 100644 --- a/c++/src/H5ArrayType.h +++ b/c++/src/H5ArrayType.h @@ -34,14 +34,13 @@ class H5_DLLCPP ArrayType : public DataType { // Assignment operator ArrayType& operator=(const ArrayType& rhs); - // Stores the rank and dimensions in memory. - void setArrayInfo(); - // Returns the number of dimensions of this array datatype. - int getArrayNDims(); + int getArrayNDims() const; + int getArrayNDims(); // deprecated // Returns the sizes of dimensions of this array datatype. - int getArrayDims(hsize_t* dims); + int getArrayDims(hsize_t* dims) const; + int getArrayDims(hsize_t* dims); // deprecated ///\brief Returns this class name. virtual H5std_string fromClass () const { return("ArrayType"); } @@ -57,10 +56,6 @@ class H5_DLLCPP ArrayType : public DataType { // Default constructor ArrayType(); - - private: - int rank; // Rank of the array - hsize_t* dimensions; // Sizes of the array dimensions }; #ifndef H5_NO_NAMESPACE } diff --git a/c++/src/H5CompType.cpp b/c++/src/H5CompType.cpp index 5668ec3..4585516 100644 --- a/c++/src/H5CompType.cpp +++ b/c++/src/H5CompType.cpp @@ -249,9 +249,8 @@ DataType CompType::getMemberDataType( unsigned member_num ) const ArrayType CompType::getMemberArrayType( unsigned member_num ) const { try { - ArrayType arraytype; + ArrayType arraytype(p_get_member_type(member_num)); f_DataType_setId(&arraytype, p_get_member_type(member_num)); - arraytype.setArrayInfo(); return(arraytype); } catch (DataTypeIException& E) { diff --git a/c++/test/tarray.cpp b/c++/test/tarray.cpp index 5d78b3c..441ef81 100644 --- a/c++/test/tarray.cpp +++ b/c++/test/tarray.cpp @@ -134,7 +134,6 @@ static void test_array_compound_array() // Create a dataset DataSet dataset = file1.createDataSet("Dataset1", arrtype, space); - dataset = file1.openDataSet("Dataset1"); // Write dataset to disk dataset.write(wdata, arrtype); @@ -351,6 +350,129 @@ static void test_array_assignment() } // end test_array_assignment() +/*------------------------------------------------------------------------- + * Function: test_array_info + * + * Purpose: Tests getting array information using the const methods. + * + * Return: None. + * + * Programmer: Binh-Minh Ribler + * April, 2016 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void test_array_info() +{ + SUBTEST("ArrayType Const Methods"); + typedef struct { // Typedef for compound datatype */ + int i; + float f[ARRAY1_DIM1]; + } s1_t; + s1_t wdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information to write + s1_t rdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information read in + hsize_t sdims1[] = {SPACE1_DIM1}; + hsize_t tdims1[] = {ARRAY1_DIM1}; + int nmemb; // Number of compound members + int ii; // counting variables + hsize_t idxi, idxj, idxk; // dimension indicing variables + H5T_class_t mclass; // Datatype class for field + + // Initialize array data to write + for (idxi =0; idxi < SPACE1_DIM1; idxi++) + for (idxj = 0; idxj < ARRAY1_DIM1; idxj++) { + wdata[idxi][idxj].i = idxi * 10 + idxj; + for(idxk = 0; idxk < ARRAY1_DIM1; idxk++) + { + float temp = idxi * 10.0 + idxj * 2.5 + idxk; + wdata[idxi][idxj].f[idxk] = temp; + } + } // end for + + try { + // Create File + H5File file1(FILENAME, H5F_ACC_TRUNC); + + // Create dataspace for datasets + DataSpace space(SPACE1_RANK, sdims1, NULL); + + /* + * Create some array datatypes, then close the file. + */ + + // Create an array of floats datatype + ArrayType arrfltype(PredType::NATIVE_FLOAT, ARRAY1_RANK, tdims1); + + // Create an array datatype of the compound datatype + ArrayType arrtype(PredType::NATIVE_UINT, ARRAY1_RANK, tdims1); + + // Create a dataset + DataSet dataset = file1.createDataSet("Dataset1", arrtype, space); + + // Write dataset to disk + dataset.write(wdata, arrtype); + + // Close array of floats field datatype + arrfltype.close(); + + // Close all + dataset.close(); + arrtype.close(); + space.close(); + file1.close(); + + // Re-open file + file1.openFile(FILENAME, H5F_ACC_RDONLY); + + // Open the dataset + dataset = file1.openDataSet("Dataset1"); + + /* + * Check the datatype array of compounds + */ + + // Verify that it is an array of compounds + DataType dstype = dataset.getDataType(); + mclass = dstype.getClass(); + verify_val(mclass==H5T_ARRAY, true, "f2_type.getClass", __LINE__, __FILE__); + + dstype.close(); + + { // Let atype_check go out of scope + // Get the array datatype, declared as const + const ArrayType atype_check = dataset.getArrayType(); + + // Check the array rank with the const method + int ndims = atype_check.getArrayNDims(); + verify_val(ndims, ARRAY1_RANK, "atype_check.getArrayNDims", __LINE__, __FILE__); + + // Get the array dimensions with the const method + hsize_t rdims1[H5S_MAX_RANK]; + atype_check.getArrayDims(rdims1); + + // Check the array dimensions + for (ii =0; ii