From 963bace0d15244768f28d549289e5e383ca9e421 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Sun, 30 Mar 2014 19:48:46 -0500 Subject: [svn-r24928] Purpose: Fix HDFFV-7907 Description: Added transform property list functions // Constructor creates a dataset transform property list. DSetMemXferPropList(const char* expression); // Sets data transform expression. void setDataTransform(const char* expression) const; void setDataTransform(const H5std_string& expression) const; // Gets data transform expression. ssize_t getDataTransform(char* exp, size_t buf_size=0) const; H5std_string getDataTransform() const; Added test file tdspl.cpp. Platforms tested: Linux/ppc64 (ostrich) Linux/32 2.6 (jam) SunOS 5.11 (emu) --- MANIFEST | 1 + c++/src/H5DxferProp.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++- c++/src/H5DxferProp.h | 13 +++++ c++/src/H5Location.cpp | 1 - c++/test/CMakeLists.txt | 1 + c++/test/Makefile.am | 2 +- c++/test/Makefile.in | 11 ++-- c++/test/h5cpputil.h | 2 + c++/test/tdspl.cpp | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ c++/test/testhdf5.cpp | 1 + 10 files changed, 297 insertions(+), 8 deletions(-) create mode 100644 c++/test/tdspl.cpp diff --git a/MANIFEST b/MANIFEST index 5411372..fb5d6b6 100644 --- a/MANIFEST +++ b/MANIFEST @@ -411,6 +411,7 @@ ./c++/test/h5cpputil.h ./c++/test/tattr.cpp ./c++/test/tcompound.cpp +./c++/test/tdspl.cpp ./c++/test/testhdf5.cpp ./c++/test/tfile.cpp ./c++/test/tfilter.cpp diff --git a/c++/src/H5DxferProp.cpp b/c++/src/H5DxferProp.cpp index bc3e0af..3379678 100644 --- a/c++/src/H5DxferProp.cpp +++ b/c++/src/H5DxferProp.cpp @@ -20,6 +20,17 @@ #include "H5IdComponent.h" #include "H5PropList.h" #include "H5DxferProp.h" +#include "H5private.h" // for HDmemset + +#include + +#ifndef H5_NO_NAMESPACE +#ifndef H5_NO_STD + using std::cerr; + using std::endl; +#endif // H5_NO_STD +#endif + #ifndef H5_NO_NAMESPACE namespace H5 { @@ -39,6 +50,17 @@ const DSetMemXferPropList DSetMemXferPropList::DEFAULT; DSetMemXferPropList::DSetMemXferPropList() : PropList(H5P_DATASET_XFER) {} //-------------------------------------------------------------------------- +// Function DSetMemXferPropList constructor +///\brief Creates a dataset transfer property list with transform +/// expression. +// Programmer: Binh-Minh Ribler - 2000 +//-------------------------------------------------------------------------- +DSetMemXferPropList::DSetMemXferPropList(const char* exp) : PropList(H5P_DATASET_XFER) +{ + setDataTransform(exp); +} + +//-------------------------------------------------------------------------- // Function DSetMemXferPropList copy constructor ///\brief Copy constructor: makes a copy of the original /// DSetMemXferPropList object @@ -175,7 +197,112 @@ void DSetMemXferPropList::getBtreeRatios( double& left, double& middle, double& } //-------------------------------------------------------------------------- -// Function: DSetMemXferPropList::setTypeConvCB +// Function: DSetMemXferPropList::setDataTransform +///\brief Sets data transform expression. +///\param expression - IN: null-terminated data transform expression (char*) +///\exception H5::PropListIException +// Programmer: Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +void DSetMemXferPropList::setDataTransform(const char* expression) const +{ + herr_t ret_value = H5Pset_data_transform( id, expression); + if( ret_value < 0 ) + { + throw PropListIException("DSetMemXferPropList::setDataTransform", + "H5Pset_data_transform failed"); + } +} + +//-------------------------------------------------------------------------- +// Function: DSetMemXferPropList::setDataTransform +///\brief This is an overloaded member function, provided for convenience. +/// It takes a reference to a \c H5std_string for the expression. +///\param expression - IN: H5std_string data transform expression +///\exception H5::PropListIException +// Programmer: Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +void DSetMemXferPropList::setDataTransform(const H5std_string& expression) const +{ + setDataTransform(expression.c_str()); +} + +//-------------------------------------------------------------------------- +// Function: DSetMemXferPropList::getDataTransform +///\brief Sets data transform expression. +///\param expression - OUT: buffer for data transform expression (char*) +///\param buf_size - IN: size of buffer for expression, including the +/// null terminator +///\exception H5::PropListIException +// Programmer: Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +ssize_t DSetMemXferPropList::getDataTransform(char* exp, size_t buf_size) const +{ + // If application does not pass in + // H5Pget_data_transform will get buf_size characters of the expression including + // the null terminator + ssize_t exp_len; + exp_len = H5Pget_data_transform(id, exp, buf_size); + + // H5Pget_data_transform returns a negative value, raise an exception + if (exp_len < 0) + { + throw PropListIException("DSetMemXferPropList::getDataTransform", + "H5Pget_data_transform failed"); + } + + // H5Pget_data_transform will put a null terminator at the end of the + // expression or at [buf_size-1] if the expression is at least the size + // of the buffer. + + // Return the actual comment length, which might be different from buf_size + return(exp_len); +} + +//-------------------------------------------------------------------------- +// Function: DSetMemXferPropList::getDataTransform +///\brief This is an overloaded member function, provided for convenience. +/// It takes no parameter and returns a \c H5std_string for the expression. +///\exception H5::PropListIException +// Programmer: Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +H5std_string DSetMemXferPropList::getDataTransform() const +{ + // Initialize string to "", so that if there is no expression, the returned + // string will be empty + H5std_string expression(""); + + // Preliminary call to get the expression's length + ssize_t exp_len = H5Pget_data_transform(id, NULL, (size_t)0); + + // If H5Pget_data_transform returns a negative value, raise an exception + if (exp_len < 0) + { + throw PropListIException("DSetMemXferPropList::getDataTransform", "H5Pget_data_transform failed"); + } + + // If expression exists, calls C routine again to get it + else if (exp_len > 0) + { + // Temporary buffer for char* expression + char* exp_C = new char[exp_len+1]; + exp_C = (char *)HDmalloc(exp_len+1); + HDmemset(exp_C, 0, exp_len+1); // clear buffer + + // Used overloaded function + exp_len = getDataTransform(exp_C, exp_len+1); + + // Convert the C expression to return + expression = exp_C; + + // Clean up resource + delete []exp_C; + } + // Return the string expression + return(expression); +} + +//-------------------------------------------------------------------------- +// Function: DSetMemXferPropList::getTypeConvCB ///\brief Sets an exception handling callback for datatype conversion /// for a dataset transfer property list. ///\param op - IN: User's function diff --git a/c++/src/H5DxferProp.h b/c++/src/H5DxferProp.h index 846082d..655f975 100644 --- a/c++/src/H5DxferProp.h +++ b/c++/src/H5DxferProp.h @@ -35,6 +35,9 @@ class H5_DLLCPP DSetMemXferPropList : public PropList { // Creates a dataset memory and transfer property list. DSetMemXferPropList(); + // Creates a dataset transform property list. + DSetMemXferPropList(const char* expression); + // Sets type conversion and background buffers. void setBuffer( size_t size, void* tconv, void* bkg ) const; @@ -47,6 +50,16 @@ class H5_DLLCPP DSetMemXferPropList : public PropList { // Gets B-tree split ratios for a dataset transfer property list. void getBtreeRatios( double& left, double& middle, double& right ) const; + // Sets data transform expression. + void setDataTransform(const char* expression) const; + void setDataTransform(const H5std_string& expression) const; + + // Gets data transform expression. + ssize_t getDataTransform(char* exp, size_t buf_size=0) const; + H5std_string getDataTransform() const; + //H5std_string getDataTransform(const size_t buf_size=0) const; + // this will collide with the first one when exp=NULL + // Sets the dataset transfer property list status to TRUE or FALSE. void setPreserve( bool status ) const; diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index 7a705f2..ead5822 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -556,7 +556,6 @@ H5std_string H5Location::getComment(const char* name, const size_t buf_size) con // Clean up resource delete []comment_C; } - // Otherwise, keep comment intact // Return the string comment return(comment); diff --git a/c++/test/CMakeLists.txt b/c++/test/CMakeLists.txt index 9966163..220d4b1 100644 --- a/c++/test/CMakeLists.txt +++ b/c++/test/CMakeLists.txt @@ -15,6 +15,7 @@ set (CPP_TEST_SRCS ${HDF5_CPP_TEST_SOURCE_DIR}/testhdf5.cpp ${HDF5_CPP_TEST_SOURCE_DIR}/tattr.cpp ${HDF5_CPP_TEST_SOURCE_DIR}/tcompound.cpp + ${HDF5_CPP_TEST_SOURCE_DIR}/tdspl.cpp ${HDF5_CPP_TEST_SOURCE_DIR}/tfile.cpp ${HDF5_CPP_TEST_SOURCE_DIR}/tfilter.cpp ${HDF5_CPP_TEST_SOURCE_DIR}/th5s.cpp diff --git a/c++/test/Makefile.am b/c++/test/Makefile.am index 687f0ca..716ed22 100644 --- a/c++/test/Makefile.am +++ b/c++/test/Makefile.am @@ -38,7 +38,7 @@ check_PROGRAMS=$(TEST_PROG) LDADD=$(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5) testhdf5_SOURCES=testhdf5.cpp dsets.cpp tattr.cpp tcompound.cpp \ - tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp \ + tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp \ ttypes.cpp tvlstr.cpp h5cpputil.cpp # Tell conclude.am that these are C++ tests. diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in index 06c3657..295d959 100644 --- a/c++/test/Makefile.in +++ b/c++/test/Makefile.in @@ -87,10 +87,10 @@ CONFIG_CLEAN_FILES = H5srcdir_str.h CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = testhdf5$(EXEEXT) am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) dsets.$(OBJEXT) \ - tattr.$(OBJEXT) tcompound.$(OBJEXT) tfile.$(OBJEXT) \ - tfilter.$(OBJEXT) th5s.$(OBJEXT) tlinks.$(OBJEXT) \ - trefer.$(OBJEXT) ttypes.$(OBJEXT) tvlstr.$(OBJEXT) \ - h5cpputil.$(OBJEXT) + tattr.$(OBJEXT) tcompound.$(OBJEXT) tdspl.$(OBJEXT) \ + tfile.$(OBJEXT) tfilter.$(OBJEXT) th5s.$(OBJEXT) \ + tlinks.$(OBJEXT) trefer.$(OBJEXT) ttypes.$(OBJEXT) \ + tvlstr.$(OBJEXT) h5cpputil.$(OBJEXT) testhdf5_OBJECTS = $(am_testhdf5_OBJECTS) testhdf5_LDADD = $(LDADD) testhdf5_DEPENDENCIES = $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5) @@ -435,7 +435,7 @@ TEST_PROG = testhdf5 # The tests depend on the hdf5 library, test library, and the c++ library LDADD = $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5) testhdf5_SOURCES = testhdf5.cpp dsets.cpp tattr.cpp tcompound.cpp \ - tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp \ + tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp \ ttypes.cpp tvlstr.cpp h5cpputil.cpp @@ -521,6 +521,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5cpputil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tattr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcompound.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdspl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testhdf5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfilter.Po@am__quote@ diff --git a/c++/test/h5cpputil.h b/c++/test/h5cpputil.h index b107045..cc135bd 100644 --- a/c++/test/h5cpputil.h +++ b/c++/test/h5cpputil.h @@ -121,6 +121,7 @@ extern "C" { #endif void test_attr(); void test_compound(); +void test_dsproplist(); void test_file(); void test_filters(); void test_links(); @@ -133,6 +134,7 @@ void test_dset(); /* Prototypes for the cleanup routines */ void cleanup_attr(); void cleanup_compound(); +void cleanup_dsproplist(); void cleanup_dsets(); void cleanup_file(); void cleanup_filters(); diff --git a/c++/test/tdspl.cpp b/c++/test/tdspl.cpp new file mode 100644 index 0000000..6364671 --- /dev/null +++ b/c++/test/tdspl.cpp @@ -0,0 +1,144 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/***************************************************************************** + FILE + tdspl.cpp - HDF5 C++ testing the dataset memory and transfer property + list functionality + + ***************************************************************************/ + +#ifdef OLD_HEADER_FILENAME +#include +#else +#include +#endif +#include + +#ifndef H5_NO_NAMESPACE +#ifndef H5_NO_STD + using std::cerr; + using std::endl; +#endif // H5_NO_STD +#endif + +#include "H5Cpp.h" // C++ API header file + +#ifndef H5_NO_NAMESPACE + using namespace H5; +#endif + +#include "h5cpputil.h" // C++ utilility header file + +const H5std_string FILENAME("tdatatransform.h5"); + +static void test_transfplist() +{ + const char* c_to_f = "(9/5.0)*x + 32"; + const char* simple = "(4/2) * ( (2 + 4)/(5 - 2.5))"; /* this equals 4.8 */ + /* inverses the utrans transform in init_test to get back original array */ + const char* utrans_inv = "(x/3)*4 - 100"; + char *c_to_f_read=NULL, *simple_read=NULL, *utrans_inv_read=NULL; + + SUBTEST("DSetMemXferPropList::set/getDataTransform()"); + try { + // Create various data set prop lists and set data transform expression. + DSetMemXferPropList dxpl_c_to_f(c_to_f); + + DSetMemXferPropList dxpl_simple; + dxpl_simple.setDataTransform(simple); + + DSetMemXferPropList dxpl_utrans_inv; + dxpl_utrans_inv.setDataTransform(utrans_inv); + + // + // Make a copy of one of those prop lists then read the data transform + // expression and verify that it's the same as the original. + // + + // Copy the prop list. + DSetMemXferPropList dxpl_c_to_f_copy; + dxpl_c_to_f_copy.copy(dxpl_c_to_f); + + // Find out the length of the transform expression, allocate the buffer + // for it, then read and verify the expression from the copied plist + ssize_t tran_len = dxpl_c_to_f_copy.getDataTransform(NULL); + c_to_f_read = (char *)HDmalloc(tran_len+1); + HDmemset(c_to_f_read, 0, tran_len+1); + dxpl_c_to_f_copy.getDataTransform(c_to_f_read, tran_len+1); + verify_val((const char*)c_to_f_read, (const char*)c_to_f, + "DSetMemXferPropList::getDataTransform", __LINE__, __FILE__); + + // + // Read the expression of each of the prop lists and verify the read + // expression + // + + // Get and verify the expression with: + // ssize_t getDataTransform(char* exp, const size_t buf_size [default=0]) + tran_len = dxpl_c_to_f.getDataTransform(NULL); + HDmemset(c_to_f_read, 0, tran_len+1); + dxpl_c_to_f.getDataTransform(c_to_f_read, tran_len+1); + verify_val((const char*)c_to_f_read, (const char*)c_to_f, + "DSetMemXferPropList::getDataTransform", __LINE__, __FILE__); + + // Get and verify the expression with: + // H5std_string DSetMemXferPropList::getDataTransform() + H5std_string simple_read = dxpl_simple.getDataTransform(); + verify_val((const char*)simple_read.c_str(), (const char*)simple, + "DSetMemXferPropList::getDataTransform", __LINE__, __FILE__); + + // Get and verify the expression with: + // ssize_t getDataTransform(char* exp, const size_t buf_size) + tran_len = dxpl_utrans_inv.getDataTransform(NULL, 0); + utrans_inv_read = (char *)HDmalloc(tran_len+1); + HDmemset(utrans_inv_read, 0, tran_len+1); + dxpl_utrans_inv.getDataTransform(utrans_inv_read, tran_len+1); + verify_val((const char*)utrans_inv_read, (const char*)utrans_inv, + "DSetMemXferPropList::getDataTransform", __LINE__, __FILE__); + + PASSED(); + } + catch (Exception E) { + issue_fail_msg("test_transfplist", __LINE__, __FILE__, E.getCDetailMsg()); + } +} + + +/**************************************************************** +** +** test_dsproplist(): Main dataset property list testing routine. +** +****************************************************************/ +#ifdef __cplusplus +extern "C" +#endif +void test_dsproplist() +{ + // Output message about test being performed + MESSAGE(5, ("Testing Generic Dataset Property Lists\n")); + + test_transfplist(); // test set/getDataTransform() + +} // test_dsproplist() + + +#ifdef __cplusplus +extern "C" +#endif +void cleanup_dsproplist() +{ + HDremove(FILENAME.c_str()); +} diff --git a/c++/test/testhdf5.cpp b/c++/test/testhdf5.cpp index fe08d6d..57210d0 100644 --- a/c++/test/testhdf5.cpp +++ b/c++/test/testhdf5.cpp @@ -84,6 +84,7 @@ main(int argc, char *argv[]) AddTest("tvlstr", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings", NULL); AddTest("ttypes", test_types, cleanup_types, "Generic Data Types", NULL); AddTest("tcompound", test_compound, cleanup_compound, "Compound Data Types", NULL); + AddTest("tdspl", test_dsproplist, cleanup_dsproplist, "Dataset Property List", NULL); AddTest("tfilter", test_filters, cleanup_filters, "Various Filters", NULL); AddTest("tlinks", test_links, cleanup_links, "Various Links", NULL); /* Comment out tests that are not done yet. - BMR, Feb 2001 -- cgit v0.12