/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /***************************************************************************** FILE tvlstr.cpp - HDF5 C++ testing the Variable-Length String functionality EXTERNAL ROUTINES/VARIABLES: ***************************************************************************/ #ifdef OLD_HEADER_FILENAME #include #else #include #endif using std::cerr; using std::endl; #include #include "H5Cpp.h" // C++ API header file using namespace H5; #include "h5test.h" #include "h5cpputil.h" // C++ utilility header file // Data file used in most test functions const H5std_string FILENAME("tvlstr.h5"); // 1-D dataset with fixed dimensions const int SPACE1_RANK = 1; const hsize_t SPACE1_DIM1 = 4; /*------------------------------------------------------------------------- * Function: test_vlstr_alloc_custom * * Purpose Test VL datatype custom memory allocation routines. * * Return None * * Description * This routine just uses malloc to allocate the memory and * increments the amount of memory allocated. It is passed * into setVlenMemManager. * * Note: exact copy from the C version. * (Not used now) *------------------------------------------------------------------------- */ #if 0 // not used now static void *test_vlstr_alloc_custom(size_t size, void *info) { void *ret_value=NULL; // Pointer to return size_t *mem_used=(size_t *)info; // Get the pointer to the memory used size_t extra; // Extra space needed /* * This weird contortion is required on the DEC Alpha to keep the * alignment correct - QAK */ extra=MAX(sizeof(void *),sizeof(size_t)); if((ret_value=HDmalloc(extra+size))!=NULL) { *(size_t *)ret_value=size; *mem_used+=size; } // end if ret_value = ((unsigned char *)ret_value) + extra; return(ret_value); } #endif /*------------------------------------------------------------------------- * Function: test_vlstr_free_custom * * Purpose Test VL datatype custom memory de-allocation routines. * * Return None * * Description * This routine just uses free to release the memory and * decrements the amount of memory allocated. It is passed * into setVlenMemManager. * * Note: exact copy from the C version. * (Not used now) *------------------------------------------------------------------------- */ #if 0 // not used now static void test_vlstr_free_custom(void *_mem, void *info) { unsigned char *mem; size_t *mem_used=(size_t *)info; // Get the pointer to the memory used size_t extra; // Extra space needed /* * This weird contortion is required on the DEC Alpha to keep the * alignment correct - QAK */ extra=MAX(sizeof(void *),sizeof(size_t)); if(_mem!=NULL) { mem=((unsigned char *)_mem)-extra; *mem_used-=*(size_t *)mem; HDfree(mem); } // end if } #endif /*------------------------------------------------------------------------- * Function: test_vlstring_dataset * * Purpose Test writing/reading VL strings on datasets. * * Return None * * Programmer Binh-Minh Ribler (use C version) * January, 2007 * *------------------------------------------------------------------------- */ // String for testing datasets // static char stastring_ds_write[1]={'A'}; // Info for a string dataset const H5std_string DSET1_NAME("String_ds"); const H5std_string DSET1_DATA("String Dataset"); static void test_vlstring_dataset() { char *dynstring_ds_write = NULL; char *string_ds_check = NULL; // Output message about test being performed SUBTEST("VL String on Datasets"); try { // Open the file H5File file1(FILENAME, H5F_ACC_TRUNC); // Create a datatype to refer to. StrType vlst(0, H5T_VARIABLE); // Open the root group. Group root = file1.openGroup("/"); // Create dataspace for the dataset. DataSpace ds_space (H5S_SCALAR); // Create an dataset in the root group. DataSet dset1 = root.createDataSet(DSET1_NAME, vlst, ds_space); // Write data to the dataset. dset1.write(DSET1_DATA, vlst); // Read and verify the dataset string as a string of chars. dset1.read(&string_ds_check, vlst); if(HDstrcmp(string_ds_check, DSET1_DATA.c_str())!=0) TestErrPrintf("Line %d: Attribute data different: DSET1_DATA=%s,string_ds_check=%s\n",__LINE__, DSET1_DATA.c_str(), string_ds_check); HDfree(string_ds_check); // note: no need for std::string test string_ds_check = NULL; // Read and verify the dataset string as an std::string. H5std_string read_str; dset1.read(read_str, vlst); if (read_str != DSET1_DATA) TestErrPrintf("Line %d: Attribute data different: DSET1_DATA=%s,read_str=%s\n",__LINE__, DSET1_DATA.c_str(), read_str.c_str()); // Close the dataset. dset1.close(); // Test scalar type dataset with 1 value. dset1 = root.createDataSet("test_scalar_small", vlst, ds_space); dynstring_ds_write = (char*)HDcalloc(1, sizeof(char)); HDmemset(dynstring_ds_write, 'A', 1); // Write data to the dataset, then read it back. dset1.write(&dynstring_ds_write, vlst); dset1.read(&string_ds_check, vlst); // Verify data read. if(HDstrcmp(string_ds_check,dynstring_ds_write)!=0) TestErrPrintf("VL string datasets don't match!, dynstring_ds_write=%s, string_ds_check=%s\n",dynstring_ds_write,string_ds_check); HDfree(string_ds_check); string_ds_check = NULL; dset1.close(); // Open dataset DSET1_NAME again. dset1 = root.openDataSet(DSET1_NAME); // Close dataset and file dset1.close(); file1.close(); PASSED(); } // end try block // Catch all exceptions. catch (Exception& E) { issue_fail_msg("test_vlstring_dataset()", __LINE__, __FILE__, E.getCDetailMsg()); } if(dynstring_ds_write) HDfree(dynstring_ds_write); if(string_ds_check) HDfree(string_ds_check); } // test_vlstring_dataset() /*------------------------------------------------------------------------- * Function: test_vlstring_array_dataset * * Purpose Test writing/reading VL string array to/from datasets. * * Return None * * Programmer Binh-Minh Ribler * July, 2009 * *------------------------------------------------------------------------- */ const H5std_string DSSTRARR_NAME("StringArray_dset"); static void test_vlstring_array_dataset() { const char *string_ds_array[SPACE1_DIM1]= { "Line 1", "Line 2", "Line 3", "Line 4" }; // Information to write // Output message about test being performed SUBTEST("VL String Array on Datasets"); H5File* file1 = NULL; try { // Create file. file1 = new H5File(FILENAME, H5F_ACC_RDWR); // Create dataspace for datasets. hsize_t dims1[] = {SPACE1_DIM1}; DataSpace ds_space(SPACE1_RANK, dims1); // Create a datatype to refer to. StrType vlst(0, H5T_VARIABLE); // Create and write a dataset. DataSet dataset(file1->createDataSet(DSSTRARR_NAME, vlst, ds_space)); dataset.write(string_ds_array, vlst); // Read and verify the dataset using strings of chars as buffer. // Note: reading by array of H5std_string doesn't work yet. char *string_ds_check[SPACE1_DIM1]; dataset.read(string_ds_check, vlst); hsize_t ii; for (ii = 0; ii < SPACE1_DIM1; ii++) { if(HDstrcmp(string_ds_check[ii], string_ds_array[ii])!=0) TestErrPrintf("Line %d: Dataset data different: written=%s,read=%s\n",__LINE__, string_ds_array[ii], string_ds_check[ii]); HDfree(string_ds_check[ii]); } // Close objects that are no longer needed. dataset.close(); ds_space.close(); // // Test with scalar data space. // // Create H5S_SCALAR data space. DataSpace scalar_space; // Create and write another dataset. DataSet dataset2(file1->createDataSet("Dataset2", vlst, scalar_space)); char *wdata2 = (char*)HDcalloc(65534, sizeof(char)); HDmemset(wdata2, 'A', 65533); dataset2.write(&wdata2, vlst); char *rdata2; dataset2.read(&rdata2, vlst); if (HDstrcmp(wdata2, rdata2)!=0) TestErrPrintf("Line %d: Dataset data different: written=%s,read=%s\n",__LINE__, wdata2, rdata2); // Release resources from second dataset operation. scalar_space.close(); dataset2.close(); HDfree(wdata2); HDfree(rdata2); // Close objects and file. dataset2.close(); vlst.close(); file1->close(); PASSED(); } // end try // Catch all exceptions. catch (Exception& E) { issue_fail_msg("test_vlstring_array_dataset()", __LINE__, __FILE__, E.getCDetailMsg()); } if(file1) delete file1; } // end test_vlstring_array_dataset() /*------------------------------------------------------------------------- * Function: test_vlstrings_special * * Purpose Test VL string code for special string cases, nil and * zero-sized. * * Return None * * Programmer Binh-Minh Ribler (use C version) * January, 2007 * *------------------------------------------------------------------------- */ static void test_vlstrings_special() { const char *wdata[SPACE1_DIM1] = {"one", "two", "", "four"}; const char *wdata2[SPACE1_DIM1] = {NULL, NULL, NULL, NULL}; char *rdata[SPACE1_DIM1]; // Information read in // Output message about test being performed. SUBTEST("Special VL Strings"); try { // Create file. H5File file1(FILENAME, H5F_ACC_TRUNC); // Create dataspace for datasets. hsize_t dims1[] = {SPACE1_DIM1}; DataSpace sid1(SPACE1_RANK, dims1); // Create a datatype to refer to. StrType vlst(0, H5T_VARIABLE); // Create a dataset. DataSet dataset(file1.createDataSet("Dataset3", vlst, sid1)); // Read from the dataset before writing data. dataset.read(rdata, vlst); // Check data read in. hsize_t ii; // counting variable for (ii=0; iiopenStrType(VLSTR_TYPE); // deprecated // Close again and reopen with constructor. vlst.close(); StrType vlst1(*file1, VLSTR_TYPE); // Close datatype and file. vlst1.close(); file1->close(); delete file1; // Open file. file1 = new H5File(FILENAME, H5F_ACC_RDWR); // Open the variable-length string datatype just created StrType vlst2(*file1, VLSTR_TYPE); // Verify character set and padding cset = vlst2.getCset(); verify_val(cset, H5T_CSET_ASCII, "StrType::getCset", __LINE__, __FILE__); pad = vlst2.getStrpad(); verify_val(pad, H5T_STR_NULLPAD, "StrType::getStrpad", __LINE__, __FILE__); // Close datatype and file vlst2.close(); file1->close(); PASSED(); } // end try block // Catch all exceptions. catch (Exception& E) { issue_fail_msg("test_vlstring_type()", __LINE__, __FILE__, E.getCDetailMsg()); } if(file1) delete file1; } // end test_vlstring_type() /*------------------------------------------------------------------------- * Function: test_compact_vlstring * * Purpose Test storing VL strings in compact datasets. * * Return None * * Programmer Binh-Minh Ribler (use C version) * January, 2007 * *------------------------------------------------------------------------- */ static void test_compact_vlstring() { // Output message about test being performed SUBTEST("VL Strings on Compact Dataset"); try { // Create file H5File file1(FILENAME, H5F_ACC_TRUNC); // Create dataspace for datasets hsize_t dims1[] = {SPACE1_DIM1}; DataSpace sid1(SPACE1_RANK, dims1); // Create a datatype to refer to StrType vlst(0, H5T_VARIABLE); // Create dataset create property list and set layout DSetCreatPropList plist; plist.setLayout(H5D_COMPACT); // Create a dataset DataSet dataset(file1.createDataSet("Dataset5", vlst, sid1, plist)); // Write dataset to disk const char *wdata[SPACE1_DIM1] = {"one", "two", "three", "four"}; dataset.write(wdata, vlst); // Read dataset from disk char *rdata[SPACE1_DIM1]; // Information read in dataset.read(rdata, vlst); // Compare data read in hsize_t i; for (i=0; i