/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 tattr.cpp - HDF5 C++ testing the functionalities associated with the C attribute interface (H5A) ***************************************************************************/ #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 FILE_BASIC("tattr_basic.h5"); const H5std_string FILE_COMPOUND("tattr_compound.h5"); const H5std_string FILE_SCALAR("tattr_scalar.h5"); const H5std_string FILE_MULTI("tattr_multi.h5"); const H5std_string FILE_DTYPE("tattr_dtype.h5"); const H5std_string ATTR_TMP_NAME("temp_attr_name"); const H5std_string FATTR_TMP_NAME("temp_fattr_name"); const size_t ATTR_MAX_DIMS = 7; /* 3-D dataset with fixed dimensions */ const int SPACE1_RANK = 3; const hsize_t SPACE1_DIM1 = 3; const hsize_t SPACE1_DIM2 = 15; const hsize_t SPACE1_DIM3 = 13; /* Object names */ const H5std_string DSET1_NAME("Dataset1"); const H5std_string GROUP1_NAME("/Group1"); const H5std_string TYPE1_NAME("/Type"); /* Attribute Rank & Dimensions */ const H5std_string ATTR1_NAME("Attr1"); const int ATTR1_RANK = 1; const hsize_t ATTR1_DIM1 = 3; int attr_data1[ATTR1_DIM1]={512,-234,98123}; /* Test data for 1st attribute */ // File attribute, using the same rank and dimensions as ATTR1_NAME's const H5std_string FATTR1_NAME("File Attr1"); const H5std_string FATTR2_NAME("File Attr2"); const H5std_string ATTR2_NAME("Attr2"); const int ATTR2_RANK = 2; const hsize_t ATTR2_DIM1 = 2; const hsize_t ATTR2_DIM2 = 2; int attr_data2[ATTR2_DIM1][ATTR2_DIM2]={{7614,-416},{197814,-3}}; /* Test data for 2nd attribute */ const H5std_string ATTR3_NAME("Attr3"); const int ATTR3_RANK = 3; const hsize_t ATTR3_DIM1 = 2; const hsize_t ATTR3_DIM2 = 2; const hsize_t ATTR3_DIM3 = 2; double attr_data3[ATTR3_DIM1][ATTR3_DIM2][ATTR3_DIM3]={{{2.3,-26.1},{0.123,-10.0}},{{981724.2,-0.91827},{2.0,23.0}}}; /* Test data for 3rd attribute */ const H5std_string ATTR4_NAME("Attr4"); const int ATTR4_RANK = 2; const hsize_t ATTR4_DIM1 = 2; const hsize_t ATTR4_DIM2 = 2; const H5std_string ATTR4_FIELDNAME1("i"); const H5std_string ATTR4_FIELDNAME2("d"); const H5std_string ATTR4_FIELDNAME3("c"); size_t attr4_field1_off=0; size_t attr4_field2_off=0; size_t attr4_field3_off=0; struct attr4_struct { int i; double d; char c; } attr_data4[ATTR4_DIM1][ATTR4_DIM2]={{{3,-26.1,'d'},{-100000, 0.123,'3'}}, {{-23,981724.2,'Q'},{0,2.0,'\n'}}}; // Test data for 4th attribute const H5std_string ATTR5_NAME("Attr5"); const int ATTR5_RANK = 0; float attr_data5 = (float)-5.123; // Test data for 5th attribute /* Info for another attribute */ const H5std_string ATTR1A_NAME("Attr1_a"); int attr_data1a[ATTR1_DIM1]={256,11945,-22107}; /**************************************************************** ** ** test_attr_basic_write(): Test basic write attribute. ** Tests integer attributes on both datasets and groups ** ****************************************************************/ static void test_attr_basic_write() { hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3}; hsize_t dims2[] = {ATTR1_DIM1}; hsize_t dims3[] = {ATTR2_DIM1,ATTR2_DIM2}; int read_data1[ATTR1_DIM1]={0}; // Buffer for reading 1st attribute hsize_t i; // Output message about test being performed SUBTEST("Basic Attribute Writing Functions"); try { // Create file H5File fid1 (FILE_BASIC, H5F_ACC_TRUNC); // Create dataspace for dataset DataSpace ds_space (SPACE1_RANK, dims1); /* * Test attribute with dataset */ // Create a dataset DataSet dataset = fid1.createDataSet(DSET1_NAME, PredType::NATIVE_UCHAR, ds_space); // Create dataspace for attribute DataSpace att_space (ATTR1_RANK, dims2); // Create a file attribute Attribute file_attr2 = fid1.createAttribute (FATTR1_NAME, PredType::NATIVE_INT, att_space); // Create a file attribute Attribute file_attr1 = fid1.createAttribute (FATTR2_NAME, PredType::NATIVE_INT, att_space); // Create an attribute for the dataset Attribute ds_attr1 = dataset.createAttribute (ATTR1_NAME, PredType::NATIVE_INT, att_space); // Try creating an attribute that already exists. This should fail // since two attributes cannot have the same name. If an exception // is not thrown for this action by createAttribute, then throw an // invalid action exception. try { Attribute invalid_attr = dataset.createAttribute (ATTR1_NAME, PredType::NATIVE_INT, att_space); // continuation here, that means no exception has been thrown throw InvalidActionException("H5File::createDataSet", "Library allowed overwrite of existing dataset"); } catch (AttributeIException E) // catching invalid creating attribute {} // do nothing, exception expected // Write attribute information ds_attr1.write (PredType::NATIVE_INT, attr_data1); // Read attribute information immediately, without closing attribute ds_attr1.read (PredType::NATIVE_INT, read_data1); // Verify values read in for(i=0; iopenAttribute(ATTR1_NAME)); // Read data from the attribute attr2->read(PredType::NATIVE_INT, &rdata); verify_val(data, rdata, "Attribute::read", __LINE__, __FILE__); // Close attribute and dataset delete attr2; delete dset2; #ifndef H5_NO_DEPRECATED_SYMBOLS // Check reference count on named datatype fid1.getObjinfo(TYPE1_NAME, statbuf); verify_val((int)statbuf.nlink, 3, "DataSet::openAttribute", __LINE__, __FILE__); #endif /* H5_NO_DEPRECATED_SYMBOLS */ } // end of second enclosing // Unlink the dataset fid1.unlink(DSET1_NAME); #ifndef H5_NO_DEPRECATED_SYMBOLS // Check reference count on named datatype fid1.getObjinfo(TYPE1_NAME, statbuf); verify_val((int)statbuf.nlink, 1, "H5File::unlink", __LINE__, __FILE__); #endif /* H5_NO_DEPRECATED_SYMBOLS */ // Unlink the named datatype fid1.unlink(TYPE1_NAME); // Close file fid1.close(); // Check size of file filesize = h5_get_file_size(FILE_DTYPE.c_str(), H5P_DEFAULT); verify_val((long)filesize, (long)empty_filesize, "Checking file size", __LINE__, __FILE__); PASSED(); } // end try block catch (Exception E) { issue_fail_msg("test_attr_dtype_shared()", __LINE__, __FILE__, E.getCDetailMsg()); } } // test_attr_dtype_shared() /**************************************************************** ** ** test_string_attr(): Test read/write string attribute. ** Tests string attributes on groups. ** ****************************************************************/ /* Info for a string attribute */ const H5std_string ATTR1_FL_STR_NAME("String_attr 1"); const H5std_string ATTR2_FL_STR_NAME("String_attr 2"); const H5std_string ATTR_VL_STR_NAME("String_attr"); const H5std_string ATTRSTR_DATA("String Attribute"); const int ATTR_LEN = 17; static void test_string_attr() { // Output message about test being performed SUBTEST("I/O on FL and VL String Attributes"); try { // Create file H5File fid1(FILE_BASIC, H5F_ACC_RDWR); // // Fixed-lenth string attributes // // Create a fixed-length string datatype to refer to. StrType fls_type(0, ATTR_LEN); // Open the root group. Group root = fid1.openGroup("/"); // Create dataspace for the attribute. DataSpace att_space (H5S_SCALAR); /* Test Attribute::write(...,const void *buf) with Fixed len string */ // Create an attribute for the root group. Attribute gr_flattr1 = root.createAttribute(ATTR1_FL_STR_NAME, fls_type, att_space); // Write data to the attribute. gr_flattr1.write(fls_type, ATTRSTR_DATA.c_str()); /* Test Attribute::write(...,const H5std_string& strg) with FL string */ // Create an attribute for the root group. Attribute gr_flattr2 = root.createAttribute(ATTR2_FL_STR_NAME, fls_type, att_space); // Write data to the attribute. gr_flattr2.write(fls_type, ATTRSTR_DATA); /* Test Attribute::read(...,void *buf) with FL string */ // Read and verify the attribute string as a string of chars. char flstring_att_check[ATTR_LEN]; gr_flattr1.read(fls_type, flstring_att_check); if(HDstrcmp(flstring_att_check, ATTRSTR_DATA.c_str())!=0) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,flstring_att_check=%s\n",__LINE__, ATTRSTR_DATA.c_str(), flstring_att_check); // Read and verify the attribute string as a string of chars; buffer // is dynamically allocated. size_t attr_size = gr_flattr1.getInMemDataSize(); char *fl_dyn_string_att_check; fl_dyn_string_att_check = new char[attr_size+1]; gr_flattr1.read(fls_type, fl_dyn_string_att_check); if(HDstrcmp(fl_dyn_string_att_check, ATTRSTR_DATA.c_str())!=0) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,flstring_att_check=%s\n",__LINE__, ATTRSTR_DATA.c_str(), fl_dyn_string_att_check); delete []fl_dyn_string_att_check; /* Test Attribute::read(...,H5std_string& strg) with FL string */ // Read and verify the attribute string as an std::string. H5std_string read_flstr1; gr_flattr1.read(fls_type, read_flstr1); if (read_flstr1 != ATTRSTR_DATA) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,read_flstr1=%s\n",__LINE__, ATTRSTR_DATA.c_str(), read_flstr1.c_str()); // Read and verify the attribute string as a string of chars. HDstrcpy(flstring_att_check, ""); gr_flattr2.read(fls_type, flstring_att_check); if(HDstrcmp(flstring_att_check, ATTRSTR_DATA.c_str())!=0) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,flstring_att_check=%s\n",__LINE__, ATTRSTR_DATA.c_str(), flstring_att_check); /* Test Attribute::read(...,H5std_string& strg) with FL string */ // Read and verify the attribute string as an std::string. H5std_string read_flstr2; gr_flattr2.read(fls_type, read_flstr2); if (read_flstr2 != ATTRSTR_DATA) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,read_flstr2=%s\n",__LINE__, ATTRSTR_DATA.c_str(), read_flstr2.c_str()); // // Variable-lenth string attributes // // Create a variable length string datatype to refer to. StrType vls_type(0, H5T_VARIABLE); // Create an attribute for the root group. Attribute gr_vlattr = root.createAttribute(ATTR_VL_STR_NAME, vls_type, att_space); // Write data to the attribute. gr_vlattr.write(vls_type, ATTRSTR_DATA); /* Test Attribute::read(...,void *buf) with Variable len string */ // Read and verify the attribute string as a string of chars. char *string_att_check; gr_vlattr.read(vls_type, &string_att_check); if(HDstrcmp(string_att_check, ATTRSTR_DATA.c_str())!=0) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,string_att_check=%s\n",__LINE__, ATTRSTR_DATA.c_str(), string_att_check); HDfree(string_att_check); /* Test Attribute::read(...,H5std_string& strg) with VL string */ // Read and verify the attribute string as an std::string. H5std_string read_str; gr_vlattr.read(vls_type, read_str); if (read_str != ATTRSTR_DATA) TestErrPrintf("Line %d: Attribute data different: ATTRSTR_DATA=%s,read_str=%s\n",__LINE__, ATTRSTR_DATA.c_str(), read_str.c_str()); PASSED(); } // end try block catch (Exception E) { issue_fail_msg("test_string_attr()", __LINE__, __FILE__, E.getCDetailMsg()); } } // test_string_attr() /**************************************************************** ** ** test_attr_exists(): Test checking for attribute existence. ** (additional attrExists tests are in test_attr_rename()) ** ****************************************************************/ static void test_attr_exists() { // Output message about test being performed SUBTEST("Check Attribute Existence"); try { // Open file. H5File fid1(FILE_BASIC, H5F_ACC_RDWR); // Open the root group. Group root = fid1.openGroup("/"); // Check for existence of attribute bool attr_exists = fid1.attrExists(ATTR1_FL_STR_NAME); if (attr_exists == false) throw InvalidActionException("H5File::attrExists", "fid1, ATTR1_FL_STR_NAMEAttribute should exist but does not"); // Check for existence of attribute attr_exists = fid1.attrExists(FATTR1_NAME); if (attr_exists == false) throw InvalidActionException("H5File::attrExists", "fid1,FATTR2_NAMEAttribute should exist but does not"); // Open a group. Group group = fid1.openGroup(GROUP1_NAME); // Check for existence of attribute attr_exists = group.attrExists(ATTR2_NAME); if (attr_exists == false) throw InvalidActionException("H5File::attrExists", "group, ATTR2_NAMEAttribute should exist but does not"); PASSED(); } // end try block catch (InvalidActionException E) { issue_fail_msg("test_attr_exists()", __LINE__, __FILE__, E.getCDetailMsg()); } catch (Exception E) { issue_fail_msg("test_attr_exists()", __LINE__, __FILE__, E.getCDetailMsg()); } } // test_attr_exists() /**************************************************************** ** ** test_attr(): Main attribute testing routine. ** ****************************************************************/ #ifdef __cplusplus extern "C" #endif void test_attr() { // Output message about test being performed MESSAGE(5, ("Testing Attributes\n")); test_attr_basic_write(); // Test basic H5A writing code test_attr_getname(); // Test overloads of Attribute::getName test_attr_rename(); // Test renaming attribute test_attr_basic_read(); // Test basic H5A reading code test_attr_compound_write(); // Test complex datatype H5A writing code test_attr_compound_read(); // Test complex datatype H5A reading code test_attr_scalar_write(); // Test scalar dataspace H5A writing code test_attr_scalar_read(); // Test scalar dataspace H5A reading code test_attr_mult_write(); // Test writing multiple attributes test_attr_mult_read(); // Test reading multiple attributes test_attr_delete(); // Test deleting attributes test_attr_dtype_shared(); // Test using shared datatypes in attributes test_string_attr(); // Test read/write string attribute test_attr_exists(); // Test H5Location::attrExists } // test_attr() /*------------------------------------------------------------------------- * Function: cleanup_attr * * Purpose: Cleanup temporary test files * * Return: none * * Programmer: Albert Cheng * July 2, 1998 * * Modifications: * *------------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" #endif void cleanup_attr() { HDremove(FILE_BASIC.c_str()); HDremove(FILE_COMPOUND.c_str()); HDremove(FILE_SCALAR.c_str()); HDremove(FILE_MULTI.c_str()); HDremove(FILE_DTYPE.c_str()); }