From 9b6f4d4937bd0e196e472e71120d6ed4b17e24f7 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Mon, 4 Sep 2017 00:41:47 -0500 Subject: Adding new C++ wrappers Description: Added wrappers for H5Tencode to class DataType and H5Tdecode to classes DataType and its subclasses. // Creates a binary object description of this datatype. void DataType::encode() // Returns the decoded type from the binary object description. virtual DataType* DataType::decode() const; virtual DataType* ArrayType::decode() const; virtual DataType* CompType::decode() const; virtual DataType* DataType::decode() const; virtual DataType* EnumType::decode() const; virtual DataType* FloatType::decode() const; virtual DataType* IntType::decode() const; virtual DataType* StrType::decode() const; virtual DataType* VarLenType::decode() const; Platforms tested: Linux/32 2.6 (jam) Linux/64 (platypus) Darwin (osx1010test) --- c++/src/H5ArrayType.cpp | 21 ++++ c++/src/H5ArrayType.h | 4 + c++/src/H5Classes.h | 2 +- c++/src/H5CompType.cpp | 21 ++++ c++/src/H5CompType.h | 4 + c++/src/H5DataType.cpp | 123 +++++++++++++++++++++-- c++/src/H5DataType.h | 19 ++++ c++/src/H5EnumType.cpp | 21 ++++ c++/src/H5EnumType.h | 4 + c++/src/H5FloatType.cpp | 23 ++++- c++/src/H5FloatType.h | 4 + c++/src/H5IntType.cpp | 21 ++++ c++/src/H5IntType.h | 4 + c++/src/H5StrType.cpp | 21 ++++ c++/src/H5StrType.h | 4 + c++/src/H5VarLenType.cpp | 21 ++++ c++/src/H5VarLenType.h | 4 + c++/test/ttypes.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++---- 18 files changed, 543 insertions(+), 30 deletions(-) diff --git a/c++/src/H5ArrayType.cpp b/c++/src/H5ArrayType.cpp index 9d4a973..c39ef35 100644 --- a/c++/src/H5ArrayType.cpp +++ b/c++/src/H5ArrayType.cpp @@ -139,6 +139,27 @@ ArrayType& ArrayType::operator=(const ArrayType& rhs) } //-------------------------------------------------------------------------- +// Function: ArrayType::decode +///\brief Returns an ArrayType object via DataType* by decoding the +/// binary object description of this type. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* ArrayType::decode() const +{ + hid_t encoded_arrtype_id; + try { + encoded_arrtype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + ArrayType *encoded_arrtype = new ArrayType; + encoded_arrtype->p_setId(encoded_arrtype_id); + return(encoded_arrtype); +} + +//-------------------------------------------------------------------------- // Function: ArrayType::getArrayNDims ///\brief Returns the number of dimensions for an array datatype. ///\return Number of dimensions diff --git a/c++/src/H5ArrayType.h b/c++/src/H5ArrayType.h index ffb8712..e3709cd 100644 --- a/c++/src/H5ArrayType.h +++ b/c++/src/H5ArrayType.h @@ -36,6 +36,10 @@ class H5_DLLCPP ArrayType : public DataType { ArrayType(const H5Location& loc, const char* name); ArrayType(const H5Location& loc, const H5std_string& name); + // Returns an ArrayType object via DataType* by decoding the + // binary object description of this type. + virtual DataType* decode() const; + // Returns the number of dimensions of this array datatype. int getArrayNDims() const; //int getArrayNDims(); // removed 1.8.18 and 1.10.1 diff --git a/c++/src/H5Classes.h b/c++/src/H5Classes.h index f0f6359..8b1e6ed 100644 --- a/c++/src/H5Classes.h +++ b/c++/src/H5Classes.h @@ -31,10 +31,10 @@ namespace H5 { class DataSpace; class AtomType; class PredType; - class EnumType; class IntType; class FloatType; class StrType; + class EnumType; class CompType; class AbstractDs; class DataSet; diff --git a/c++/src/H5CompType.cpp b/c++/src/H5CompType.cpp index f7862c9..95fddc1 100644 --- a/c++/src/H5CompType.cpp +++ b/c++/src/H5CompType.cpp @@ -124,6 +124,27 @@ CompType::CompType(const H5Location& loc, const H5std_string& dtype_name) : Data } //-------------------------------------------------------------------------- +// Function: CompType::decode +///\brief Returns a CompType object via DataType* by decoding the +/// binary object description of this datatype. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* CompType::decode() const +{ + hid_t encoded_cmptype_id; + try { + encoded_cmptype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + CompType *encoded_cmptype = new CompType; + encoded_cmptype->p_setId(encoded_cmptype_id); + return(encoded_cmptype); +} + +//-------------------------------------------------------------------------- // Function: CompType::getNmembers ///\brief Returns the number of members in this compound datatype. ///\return Number of members diff --git a/c++/src/H5CompType.h b/c++/src/H5CompType.h index 018d875..bf687de 100644 --- a/c++/src/H5CompType.h +++ b/c++/src/H5CompType.h @@ -44,6 +44,10 @@ class H5_DLLCPP CompType : public DataType { CompType(const H5Location& loc, const char* name); CompType(const H5Location& loc, const H5std_string& name); + // Returns a CompType object via DataType* by decoding the binary + // object description of this type. + virtual DataType* decode() const; + // Returns the type class of the specified member of this compound // datatype. It provides to the user a way of knowing what type // to create another datatype of the same class diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index 57f9361..11b30cc 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -48,7 +48,7 @@ using std::endl; ///\brief Default constructor: Creates a stub datatype // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- -DataType::DataType() : H5Object(), id(H5I_INVALID_HID) {} +DataType::DataType() : H5Object(), id(H5I_INVALID_HID), encoded_buf(NULL), buf_size(0) {} //-------------------------------------------------------------------------- // Function: DataType overloaded constructor @@ -63,7 +63,7 @@ DataType::DataType() : H5Object(), id(H5I_INVALID_HID) {} // Removed second argument, "predefined", after changing to the // new ref counting mechanism that relies on C's ref counting. //-------------------------------------------------------------------------- -DataType::DataType(const hid_t existing_id) : H5Object(), id(existing_id) +DataType::DataType(const hid_t existing_id) : H5Object(), id(existing_id), encoded_buf(NULL), buf_size(0) { incRefCount(); // increment number of references to this id } @@ -76,7 +76,7 @@ DataType::DataType(const hid_t existing_id) : H5Object(), id(existing_id) ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- -DataType::DataType(const H5T_class_t type_class, size_t size) : H5Object() +DataType::DataType(const H5T_class_t type_class, size_t size) : H5Object(), encoded_buf(NULL), buf_size(0) { // Call C routine to create the new datatype id = H5Tcreate(type_class, size); @@ -100,7 +100,7 @@ DataType::DataType(const H5T_class_t type_class, size_t size) : H5Object() // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- -DataType::DataType(const H5Location& loc, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object() +DataType::DataType(const H5Location& loc, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), encoded_buf(NULL), buf_size(0) { id = H5Location::p_dereference(loc.getId(), ref, ref_type, plist, "constructor - by dereference"); } @@ -119,7 +119,7 @@ DataType::DataType(const H5Location& loc, const void* ref, H5R_type_t ref_type, // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- - /* DataType::DataType(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(H5I_INVALID_HID) + /* DataType::DataType(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(H5I_INVALID_HID), encoded_buf(NULL), buf_size(0) { id = H5Location::p_dereference(attr.getId(), ref, ref_type, plist, "constructor - by dereference"); } @@ -130,7 +130,7 @@ DataType::DataType(const H5Location& loc, const void* ref, H5R_type_t ref_type, ///\brief Copy constructor: makes a copy of the original DataType object // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- -DataType::DataType(const DataType& original) : H5Object(), id(original.id) +DataType::DataType(const DataType& original) : H5Object(), id(original.id), encoded_buf(NULL), buf_size(0) { incRefCount(); // increment number of references to this id } @@ -148,7 +148,7 @@ DataType::DataType(const DataType& original) : H5Object(), id(original.id) // unnecessarily and will produce undefined behavior. // -BMR, Apr 2015 //-------------------------------------------------------------------------- -DataType::DataType(const PredType& pred_type) : H5Object() +DataType::DataType(const PredType& pred_type) : H5Object(), encoded_buf(NULL), buf_size(0) { // Call C routine to copy the datatype id = H5Tcopy(pred_type.getId()); @@ -170,7 +170,7 @@ DataType::DataType(const PredType& pred_type) : H5Object() // improve usability. // -BMR, Dec 2016 //-------------------------------------------------------------------------- -DataType::DataType(const H5Location& loc, const char *dtype_name) : H5Object() +DataType::DataType(const H5Location& loc, const char *dtype_name) : H5Object(), encoded_buf(NULL), buf_size(0) { id = p_opentype(loc, dtype_name); } @@ -189,7 +189,7 @@ DataType::DataType(const H5Location& loc, const char *dtype_name) : H5Object() // improve usability. // -BMR, Dec 2016 //-------------------------------------------------------------------------- -DataType::DataType(const H5Location& loc, const H5std_string& dtype_name) : H5Object() +DataType::DataType(const H5Location& loc, const H5std_string& dtype_name) : H5Object(), encoded_buf(NULL), buf_size(0) { id = p_opentype(loc, dtype_name.c_str()); } @@ -248,6 +248,102 @@ void DataType::copy(const DataSet& dset) } //-------------------------------------------------------------------------- +// Function: DataType::p_decode +// Purpose Returns an id of a type by decoding the binary object +/// description of this datatype. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +hid_t DataType::p_decode() const +{ + // Make sure that the buffer can be decoded + if (encoded_buf == NULL) + { + throw DataTypeIException("DataType::p_decode", "No encoded buffer"); + } + + // Call C function to decode the binary object description + hid_t encoded_dtype_id = H5Tdecode(encoded_buf); + + // If H5Tdecode fails, raise exception + if (encoded_dtype_id < 0) + { + throw DataTypeIException("DataType::p_decode", "H5Tdecode failed"); + } + else + { + return(encoded_dtype_id); + } +} + +//-------------------------------------------------------------------------- +// Function: DataType::decode +///\brief Returns a DataType instance by decoding the binary object +/// description of this datatype. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* DataType::decode() const +{ + hid_t encoded_dtype_id; + try { + encoded_dtype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + DataType *encoded_dtype = new DataType; + encoded_dtype->p_setId(encoded_dtype_id); + return(encoded_dtype); +} + +//-------------------------------------------------------------------------- +// Function: DataType::encode +///\brief Creates a binary object description of this datatype. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +void DataType::encode() +{ + // Call H5Tencode passing in null to determine the size of the buffer + herr_t ret_value = H5Tencode(id, NULL, &buf_size); + if (ret_value < 0) + { + throw DataTypeIException("DataType::encode", "Failed to get buf_size"); + } + + // Allocate buffer and call C function again to encode + if (buf_size > 0) + { + encoded_buf = (unsigned char *)HDcalloc((size_t)1, buf_size); + ret_value = H5Tencode(id, encoded_buf, &buf_size); + if (ret_value < 0) + { + throw DataTypeIException("DataType::encode", "H5Tencode failed"); + } + } + else + { + throw DataTypeIException("DataType::encode", "Failed to allocate buffer for encoding"); + } +} + +//-------------------------------------------------------------------------- +// Function: DataType::hasBinaryDesc +///\brief Determines whether this datatype has a binary object +/// description. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +bool DataType::hasBinaryDesc() const +{ + if (encoded_buf != NULL) + return true; + else + return false; +} + +//-------------------------------------------------------------------------- // Function: DataType::operator= ///\brief Assignment operator ///\param rhs - IN: Reference to the existing datatype @@ -827,8 +923,15 @@ void DataType::close() { throw DataTypeIException(inMemFunc("close"), "H5Tclose failed"); } - // reset the id + // Reset the id id = H5I_INVALID_HID; + + // Free and reset buffer of encoded object description if it's been used + if (encoded_buf != NULL) + { + HDfree(encoded_buf); + buf_size = 0; + } } } diff --git a/c++/src/H5DataType.h b/c++/src/H5DataType.h index 32a79fa..50d2fc1 100644 --- a/c++/src/H5DataType.h +++ b/c++/src/H5DataType.h @@ -50,6 +50,13 @@ class H5_DLLCPP DataType : public H5Object { // Copies the datatype of dset to this datatype object. void copy(const DataSet& dset); + // Returns a DataType instance by decoding the binary object + // description of this datatype. + virtual DataType* decode() const; + + // Creates a binary object description of this datatype. + void encode(); + // Returns the datatype class identifier. H5T_class_t getClass() const; @@ -130,6 +137,9 @@ class H5_DLLCPP DataType : public H5Object { // Default constructor DataType(); + // Determines whether this datatype has a binary object description. + bool hasBinaryDesc() const; + // Gets the datatype id. virtual hid_t getId() const; @@ -140,6 +150,10 @@ class H5_DLLCPP DataType : public H5Object { #ifndef DOXYGEN_SHOULD_SKIP_THIS hid_t id; // HDF5 datatype id + // Returns an id of a type by decoding the binary object + // description of this datatype. + hid_t p_decode() const; + // Sets the datatype id. virtual void p_setId(const hid_t new_id); @@ -149,6 +163,11 @@ class H5_DLLCPP DataType : public H5Object { #endif // DOXYGEN_SHOULD_SKIP_THIS private: + // Buffer for binary object description of this datatype, allocated + // in DataType::encode and used in DataType::decode + unsigned char *encoded_buf; + size_t buf_size; + // Friend function to set DataType id. For library use only. friend void f_DataType_setId(DataType* dtype, hid_t new_id); diff --git a/c++/src/H5EnumType.cpp b/c++/src/H5EnumType.cpp index a96239c..f9046be 100644 --- a/c++/src/H5EnumType.cpp +++ b/c++/src/H5EnumType.cpp @@ -146,6 +146,27 @@ EnumType::EnumType(const H5Location& loc, const H5std_string& dtype_name) : Data } //-------------------------------------------------------------------------- +// Function: EnumType::decode +///\brief Returns an EnumType object via DataType* by decoding the +/// binary object description of this type. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* EnumType::decode() const +{ + hid_t encoded_cmptype_id; + try { + encoded_cmptype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + EnumType *encoded_cmptype = new EnumType; + encoded_cmptype->p_setId(encoded_cmptype_id); + return(encoded_cmptype); +} + +//-------------------------------------------------------------------------- // Function: EnumType::insert ///\brief Inserts a new member to this enumeration datatype. ///\param name - IN: Name of the new member diff --git a/c++/src/H5EnumType.h b/c++/src/H5EnumType.h index fc8089e..6468bf7 100644 --- a/c++/src/H5EnumType.h +++ b/c++/src/H5EnumType.h @@ -40,6 +40,10 @@ class H5_DLLCPP EnumType : public DataType { EnumType(const H5Location& loc, const char* name); EnumType(const H5Location& loc, const H5std_string& name); + // Returns an EnumType object via DataType* by decoding the + // binary object description of this type. + virtual DataType* decode() const; + // Returns the number of members in this enumeration datatype. int getNmembers () const; diff --git a/c++/src/H5FloatType.cpp b/c++/src/H5FloatType.cpp index 6bb3fd6..66a7466 100644 --- a/c++/src/H5FloatType.cpp +++ b/c++/src/H5FloatType.cpp @@ -71,7 +71,7 @@ FloatType::FloatType(const hid_t existing_id) : AtomType( existing_id ) {} FloatType::FloatType(const FloatType& original) : AtomType( original ){} //-------------------------------------------------------------------------- -// Function: EnumType overloaded constructor +// Function: FloatType overloaded constructor ///\brief Gets the floating-point datatype of the specified dataset ///\param dataset - IN: Dataset that this floating-point datatype /// associates with @@ -128,6 +128,27 @@ FloatType::FloatType(const H5Location& loc, const H5std_string& dtype_name) : At } //-------------------------------------------------------------------------- +// Function: FloatType::decode +///\brief Returns an FloatType object via DataType* by decoding the +/// binary object description of this type. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* FloatType::decode() const +{ + hid_t encoded_flttype_id; + try { + encoded_flttype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + FloatType *encoded_flttype = new FloatType; + encoded_flttype->p_setId(encoded_flttype_id); + return(encoded_flttype); +} + +//-------------------------------------------------------------------------- // Function: FloatType::getFields ///\brief Retrieves floating point datatype bit field information. ///\param spos - OUT: Retrieved floating-point sign bit diff --git a/c++/src/H5FloatType.h b/c++/src/H5FloatType.h index e84f50b..4f277c3 100644 --- a/c++/src/H5FloatType.h +++ b/c++/src/H5FloatType.h @@ -35,6 +35,10 @@ class H5_DLLCPP FloatType : public AtomType { FloatType(const H5Location& loc, const char* name); FloatType(const H5Location& loc, const H5std_string& name); + // Returns an FloatType object via DataType* by decoding the + // binary object description of this type. + virtual DataType* decode() const; + // Retrieves the exponent bias of a floating-point type. size_t getEbias() const; diff --git a/c++/src/H5IntType.cpp b/c++/src/H5IntType.cpp index fb7e476..8408732 100644 --- a/c++/src/H5IntType.cpp +++ b/c++/src/H5IntType.cpp @@ -127,6 +127,27 @@ IntType::IntType(const H5Location& loc, const H5std_string& dtype_name) : AtomTy } //-------------------------------------------------------------------------- +// Function: IntType::decode +///\brief Returns an IntType object via DataType* by decoding the +/// binary object description of this type. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* IntType::decode() const +{ + hid_t encoded_inttype_id; + try { + encoded_inttype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + IntType *encoded_inttype = new IntType; + encoded_inttype->p_setId(encoded_inttype_id); + return(encoded_inttype); +} + +//-------------------------------------------------------------------------- // Function: IntType::getSign ///\brief Retrieves the sign type for an integer type. ///\return Valid sign type diff --git a/c++/src/H5IntType.h b/c++/src/H5IntType.h index 82a7cfd..54a4975 100644 --- a/c++/src/H5IntType.h +++ b/c++/src/H5IntType.h @@ -35,6 +35,10 @@ class H5_DLLCPP IntType : public AtomType { IntType(const H5Location& loc, const char* name); IntType(const H5Location& loc, const H5std_string& name); + // Returns an IntType object via DataType* by decoding the + // binary object description of this type. + virtual DataType* decode() const; + // Retrieves the sign type for an integer type H5T_sign_t getSign() const; diff --git a/c++/src/H5StrType.cpp b/c++/src/H5StrType.cpp index d5fb744..cbb2103 100644 --- a/c++/src/H5StrType.cpp +++ b/c++/src/H5StrType.cpp @@ -181,6 +181,27 @@ StrType::StrType(const H5Location& loc, const H5std_string& dtype_name) : AtomTy } //-------------------------------------------------------------------------- +// Function: StrType::decode +///\brief Returns an StrType object via DataType* by decoding the +/// binary object description of this type. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* StrType::decode() const +{ + hid_t encoded_strtype_id; + try { + encoded_strtype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + StrType *encoded_strtype = new StrType; + encoded_strtype->p_setId(encoded_strtype_id); + return(encoded_strtype); +} + +//-------------------------------------------------------------------------- // Function: StrType::getCset ///\brief Retrieves the character set type of this string datatype. ///\return Character set type, which can be: diff --git a/c++/src/H5StrType.h b/c++/src/H5StrType.h index abac8de..fd0402e 100644 --- a/c++/src/H5StrType.h +++ b/c++/src/H5StrType.h @@ -41,6 +41,10 @@ class H5_DLLCPP StrType : public AtomType { StrType(const H5Location& loc, const char* name); StrType(const H5Location& loc, const H5std_string& name); + // Returns an StrType object via DataType* by decoding the + // binary object description of this type. + virtual DataType* decode() const; + // Retrieves the character set type of this string datatype. H5T_cset_t getCset() const; diff --git a/c++/src/H5VarLenType.cpp b/c++/src/H5VarLenType.cpp index 22e1a66..fcea8cd 100644 --- a/c++/src/H5VarLenType.cpp +++ b/c++/src/H5VarLenType.cpp @@ -109,6 +109,27 @@ VarLenType::VarLenType(const H5Location& loc, const H5std_string& dtype_name) : } //-------------------------------------------------------------------------- +// Function: VarLenType::decode +///\brief Returns an VarLenType object via DataType* by decoding the +/// binary object description of this type. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - Aug 2017 +//-------------------------------------------------------------------------- +DataType* VarLenType::decode() const +{ + hid_t encoded_vltype_id; + try { + encoded_vltype_id = p_decode(); + } + catch (DataTypeIException &err) { + throw; + } + VarLenType *encoded_vltype = new VarLenType; + encoded_vltype->p_setId(encoded_vltype_id); + return(encoded_vltype); +} + +//-------------------------------------------------------------------------- // Function: VarLenType destructor ///\brief Properly terminates access to this datatype. // Programmer Binh-Minh Ribler - May, 2004 diff --git a/c++/src/H5VarLenType.h b/c++/src/H5VarLenType.h index 4048a4e..17d812f 100644 --- a/c++/src/H5VarLenType.h +++ b/c++/src/H5VarLenType.h @@ -29,6 +29,10 @@ class H5_DLLCPP VarLenType : public DataType { // on the specified base type. VarLenType(const DataType* base_type); + // Returns an VarLenType object via DataType* by decoding the + // binary object description of this type. + virtual DataType* decode() const; + ///\brief Returns this class name. virtual H5std_string fromClass () const { return("VarLenType"); } diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp index f76f780..ec644a8 100644 --- a/c++/test/ttypes.cpp +++ b/c++/test/ttypes.cpp @@ -80,6 +80,12 @@ typedef enum int_t { INT_LONG, INT_ULONG, INT_LLONG, INT_ULLONG, INT_OTHER } int_t; +typedef struct { + int a; + float b; + long c; + double d; +} src_typ_t; /*------------------------------------------------------------------------- * Function: test_classes @@ -125,9 +131,7 @@ static void test_classes() * * Purpose Test datatype copy functionality * - * Return Success: 0 - * - * Failure: number of errors + * Return None * * Programmer Binh-Minh Ribler (using C version) * January, 2007 @@ -183,9 +187,7 @@ static void test_copy() * * Purpose Tests query functions of compound and enumeration types. * - * Return Success: 0 - * - * Failure: number of errors + * Return None * * Programmer Binh-Minh Ribler (use C version) * January, 2007 @@ -200,12 +202,6 @@ const H5std_string EnumT_NAME("Enum_type"); static void test_query() { - typedef struct { - int a; - float b; - long c; - double d; - } src_typ_t; short enum_val; // Output message about test being performed @@ -317,9 +313,7 @@ static void test_query() * * Purpose Tests transient datatypes. * - * Return Success: 0 - * - * Failure: number of errors + * Return None * * Programmer Binh-Minh Ribler (use C version) * January, 2007 @@ -396,9 +390,7 @@ static void test_transient () * * Purpose Tests named datatypes. * - * Return Success: 0 - * - * Failure: number of errors + * Return None * * Programmer Binh-Minh Ribler (use C version) * January, 2007 @@ -556,6 +548,229 @@ static void test_named () } // test_named +/*------------------------------------------------------------------------- + * Function: test_encode_decode + * + * Purpose Test datatype encode/decode functionality. + * + * Return None + * + * Programmer Binh-Minh Ribler (using C version) + * August, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +const H5std_string filename3("encode_decode.h5"); +const int ARRAY1_RANK = 1; +const int ARRAY1_DIM = 10; +static void test_encode_decode() +{ + short enum_val; + + SUBTEST("DataType::encode() and DataType::decode()"); + try { + // Create the file. + H5File file(filename3, H5F_ACC_TRUNC); + + // + // Test with CompType + // + + // Create a compound datatype + CompType cmptyp(sizeof(src_typ_t)); + + cmptyp.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT); + cmptyp.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_FLOAT); + cmptyp.insertMember("c", HOFFSET(src_typ_t, c), PredType::NATIVE_LONG); + cmptyp.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_DOUBLE); + + // Encode compound type in its buffer + cmptyp.encode(); + + // Verify that encoding had been done + verify_val(cmptyp.hasBinaryDesc(), true, "DataType::encode", __LINE__, __FILE__); + + // Decode compound type's buffer to a new CompType + CompType* decoded_cmp_ptr(static_cast(cmptyp.decode())); + + // Verify that the datatype was copied exactly via encoding/decoding + verify_val(cmptyp == *decoded_cmp_ptr, true, "DataType::decode", __LINE__, __FILE__); + + // Verify again via querying member number and member index by name. + verify_val(decoded_cmp_ptr->getNmembers(), 4, "DataType::decode", __LINE__, __FILE__); + verify_val(decoded_cmp_ptr->getMemberIndex("c"), 2, "DataType::decode", __LINE__, __FILE__); + + // Create a CompType instance from the pointer and verify it + CompType cmptyp_clone(*decoded_cmp_ptr); + verify_val(cmptyp == cmptyp_clone, true, "DataType::decode", __LINE__, __FILE__); + verify_val(cmptyp_clone.getNmembers(), 4, "DataType::decode", __LINE__, __FILE__); + verify_val(cmptyp_clone.getMemberIndex("c"), 2, "DataType::decode", __LINE__, __FILE__); + + delete decoded_cmp_ptr; + + // + // Test with EnumType + // + + // Create a enumerate datatype + EnumType enumtyp(sizeof(short)); + + enumtyp.insert("RED", (enum_val=0,&enum_val)); + enumtyp.insert("GREEN", (enum_val=1,&enum_val)); + enumtyp.insert("BLUE", (enum_val=2,&enum_val)); + enumtyp.insert("ORANGE", (enum_val=3,&enum_val)); + enumtyp.insert("YELLOW", (enum_val=4,&enum_val)); + + // Encode compound type in a buffer + enumtyp.encode(); + + // Verify that encoding had been done + verify_val(enumtyp.hasBinaryDesc(), true, "DataType::encode", __LINE__, __FILE__); + + // Decode enumeration type's buffer to a new EnumType + EnumType* decoded_enum_ptr(static_cast(enumtyp.decode())); + + // Verify that the datatype was copied exactly via encoding/decoding + verify_val(enumtyp == *decoded_enum_ptr, true, "DataType::decode", __LINE__, __FILE__); + + // Verify again via querying member number and member index by name. + verify_val(decoded_enum_ptr->getNmembers(), 5, "DataType::decode", __LINE__, __FILE__); + verify_val(decoded_enum_ptr->getMemberIndex("GREEN"), 1, "DataType::decode", __LINE__, __FILE__); + + // Create a EnumType instance from the pointer and verify it + EnumType enumtyp_clone(*decoded_enum_ptr); + verify_val(enumtyp == enumtyp_clone, true, "DataType::decode", __LINE__, __FILE__); + verify_val(enumtyp_clone.getNmembers(), 5, "DataType::decode", __LINE__, __FILE__); + verify_val(enumtyp_clone.getMemberIndex("GREEN"), 1, "DataType::decode", __LINE__, __FILE__); + + delete decoded_enum_ptr; + + // + // Test with variable-length string + // + + // Create a variable-length string type + StrType vlsttyp(PredType::C_S1); + vlsttyp.setSize(H5T_VARIABLE); + + // Encode the variable-length type in its buffer + vlsttyp.encode(); + + // Verify that encoding had been done + verify_val(vlsttyp.hasBinaryDesc(), true, "DataType::encode", __LINE__, __FILE__); + + // Decode the variable-length type's buffer to a new StrType + StrType* decoded_str_ptr(static_cast(vlsttyp.decode())); + + verify_val(vlsttyp == *decoded_str_ptr, true, "DataType::decode", __LINE__, __FILE__); + verify_val(decoded_str_ptr->isVariableStr(), true, "DataType::decode", __LINE__, __FILE__); + + delete decoded_str_ptr; + + // Test decoding the type by way of DataType* + + // Decode variable-length string type to a new DataType + DataType* decoded_vlstr_ptr(vlsttyp.decode()); + + // Create a StrType instance from the DataType object and verify it + StrType decoded_vlsttyp(decoded_vlstr_ptr->getId()); + verify_val(vlsttyp == decoded_vlsttyp, true, "DataType::decode", __LINE__, __FILE__); + verify_val(decoded_vlsttyp.isVariableStr(), true, "DataType::decode", __LINE__, __FILE__); + + delete decoded_vlstr_ptr; + + // + // Test with ArrayType + // + + hsize_t tdims1[] = {ARRAY1_DIM}; + + // Create an array datatype of the compound datatype + ArrayType arrtyp(cmptyp, ARRAY1_RANK, tdims1); + + // Encode the array type in its buffer + arrtyp.encode(); + + // Verify that encoding had been done + verify_val(arrtyp.hasBinaryDesc(), true, "DataType::encode", __LINE__, __FILE__); + + // Create an ArrayType instance from the decoded pointer and verify it + ArrayType* decoded_arr_ptr(static_cast(arrtyp.decode())); + + verify_val(arrtyp == *decoded_arr_ptr, true, "DataType::decode", __LINE__, __FILE__); + + delete decoded_arr_ptr; + + // Test decoding the type by way of DataType* + + // Decode the array type's buffer + DataType *decoded_dt_ptr = arrtyp.decode(); + + // Create a ArrayType instance from the decoded pointer and verify it + ArrayType decoded_arrtyp(decoded_dt_ptr->getId()); + verify_val(arrtyp == decoded_arrtyp, true, "DataType::decode", __LINE__, __FILE__); + verify_val(decoded_arrtyp.getArrayNDims(), ARRAY1_RANK, "DataType::decode", __LINE__, __FILE__); + + delete decoded_dt_ptr; + + // + // Test with IntType + // + + // Create an int datatype + IntType inttyp(PredType::NATIVE_UINT); + + // Encode the array type in its buffer + inttyp.encode(); + + // Verify that encoding had been done + verify_val(inttyp.hasBinaryDesc(), true, "DataType::encode", __LINE__, __FILE__); + + // Create an IntType instance from the decoded pointer and verify it + IntType* decoded_int_ptr(static_cast(inttyp.decode())); + H5T_sign_t int_sign = decoded_int_ptr->getSign(); + verify_val(int_sign, H5T_SGN_NONE, "DataType::decode", __LINE__, __FILE__); + verify_val(inttyp == *decoded_int_ptr, true, "DataType::decode", __LINE__, __FILE__); + + delete decoded_int_ptr; + + // + // Test decoding FloatType by way of DataType* + // + + // Create a float datatype + FloatType flttyp(PredType::NATIVE_FLOAT); + + // Encode the float type in its buffer + flttyp.encode(); + + // Verify that encoding had been done + verify_val(flttyp.hasBinaryDesc(), true, "DataType::encode", __LINE__, __FILE__); + + // Decode the array type's buffer + DataType* decoded_flt_ptr(flttyp.decode()); + + // Create a IntType instance from the decoded pointer and verify it + FloatType decoded_flttyp(decoded_flt_ptr->getId()); + verify_val(flttyp == decoded_flttyp, true, "DataType::decode", __LINE__, __FILE__); + + H5std_string norm_string; + H5T_norm_t mant_norm = decoded_flttyp.getNorm(norm_string); + //verify_val(decoded_flttyp.isVariableStr(), true, "DataType::decode", __LINE__, __FILE__); + + delete decoded_flt_ptr; + + PASSED(); + } + catch (Exception& E) + { + issue_fail_msg("test_encode_decode", __LINE__, __FILE__, E.getCDetailMsg()); + } +} + + /**************************************************************** ** ** test_types(): Main datatypes testing routine. @@ -573,6 +788,7 @@ void test_types() test_query(); test_transient(); test_named(); + test_encode_decode(); } // test_types() -- cgit v0.12