//-------------------------------------------------------------------------- // Function: H5Object::iterateAttrs ///\brief Iterates a user's function over all the attributes of an H5 /// object, which may be a group, dataset or named datatype. ///\param user_op - IN: User's function to operate on each attribute ///\param _idx - IN/OUT: Starting (IN) and ending (OUT) attribute indices ///\param op_data - IN: User's data to pass to user's operator function ///\return Returned value of the last operator if it was non-zero, or /// zero if all attributes were processed ///\exception H5::AttributeIException ///\par Description /// The signature of user_op is /// void (*)(H5::H5Object&, H5std_string, void*). /// For information, please refer to the C layer Reference Manual /// at: /// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5A.html#Annot-Iterate // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- int H5Object::iterateAttrs( attr_operator_t user_op, unsigned *_idx, void *op_data ) { // store the user's function and data UserData4Aiterate* userData = new UserData4Aiterate; userData->opData = op_data; userData->op = user_op; userData->object = this; // call the C library routine H5Aiterate2 to iterate the attributes hsize_t idx = _idx ? (hsize_t)*_idx : 0; int ret_value = H5Aiterate2(getId(), H5_INDEX_NAME, H5_ITER_INC, &idx, userAttrOpWrpr, (void *) userData); // release memory delete userData; if( ret_value >= 0 ) { /* Pass back update index value to calling code */ if (_idx) *_idx = (unsigned)idx; return( ret_value ); } else // raise exception when H5Aiterate returns a negative value throw AttributeIException(inMemFunc("iterateAttrs"), "H5Aiterate2 failed"); }
/* * Class: hdf_hdf5lib_H5 * Method: H5Aiterate * Signature: (JIIJLjava/lang/Object;Ljava/lang/Object;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Aiterate (JNIEnv *env, jclass clss, jlong grp_id, jint idx_type, jint order, jlong idx, jobject callback_op, jobject op_data) { hsize_t start_idx = (hsize_t)idx; herr_t status = -1; ENVPTR->GetJavaVM(ENVPAR &jvm); visit_callback = callback_op; if ((op_data == NULL) || (callback_op == NULL)) { h5nullArgument(env, "H5Literate_by_name: op_data or callback_op is NULL"); } /* end if */ else { status = H5Aiterate2((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, (hsize_t*)&start_idx, (H5A_operator2_t)H5A_iterate_cb, (void*)op_data); if (status < 0) h5libraryError(env); } /* end else */ return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Aiterate */
//-***************************************************************************** CprData::CprData( H5Node & iParentGroup, int32_t iArchiveVersion, const std::string &iName ) : m_subPropertyMutexes( NULL ) { ABCA_ASSERT( iParentGroup.isValidObject(), "invalid parent group" ); // If our group exists, open it. If it does not, this is not a problem! // It just means we don't have any subproperties. if ( !GroupExists( iParentGroup, iName ) ) { // No group. It's okay! // Just return - it means we have no subprops! return; } m_group = OpenGroup( iParentGroup, iName.c_str() ); ABCA_ASSERT( m_group.isValidObject(), "Could not open compound property group named: " << iName << ", H5Gopen2 failed" ); // Do the visiting to gather property names. CprAttrVisitor visitor; HDF5Hierarchy* h5HPtr = iParentGroup.getH5HPtr(); if ( h5HPtr ) { h5HPtr->visitAllAttributes( iParentGroup.getRef(), iName, visitor ); } else { try { herr_t status = H5Aiterate2( m_group.getObject(), H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, CprVisitAllAttrsCB, ( void * )&visitor ); ABCA_ASSERT( status >= 0, "CprData::CprData(): H5Aiterate failed" ); } catch ( std::exception & exc ) { ABCA_THROW( "Could not attr iterate property group named: " << iName << ", reason: " << exc.what() ); } catch ( ... ) { ABCA_THROW( "Could not attr iterate property group named: " << iName << ", unknown reason" ); } } size_t index = 0; m_propertyHeaders.resize( visitor.properties.size() ); m_subPropertyMutexes = new Alembic::Util::mutex[ visitor.properties.size() ]; // For each property name, read the various pieces of information for ( std::vector<std::string>::iterator siter = visitor.properties.begin(); siter != visitor.properties.end(); ++siter, ++index ) { m_subProperties[(*siter)] = index; m_propertyHeaders[index].name = (*siter); m_propertyHeaders[index].numSamples = 0; m_propertyHeaders[index].firstChangedIndex = 0; m_propertyHeaders[index].lastChangedIndex = 0; m_propertyHeaders[index].isScalarLike = false; } }
/**************************************************************** ** ** test_iter_attr(): Test attribute iteration functionality ** ****************************************************************/ static void test_iter_attr(hid_t fapl, hbool_t new_format) { hid_t file; /* File ID */ hid_t dataset; /* Common Dataset ID */ hid_t filespace; /* Common dataspace ID */ hid_t attribute; /* Attribute ID */ int i; /* counting variable */ hsize_t idx; /* Index in the attribute list */ char name[NAMELEN]; /* temporary name buffer */ char *anames[NATTR]; /* Names of the attributes created */ iter_info info; /* Custom iteration information */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Attribute Iteration Functionality\n")); /* Create the test file with the datasets */ file = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(file, FAIL, "H5Fcreate"); filespace = H5Screate(H5S_SCALAR); CHECK(filespace, FAIL, "H5Screate"); dataset = H5Dcreate2(file, "Dataset", H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dcreate2"); for(i = 0; i < NATTR; i++) { sprintf(name, "Attribute %02d", i); attribute = H5Acreate2(dataset, name, H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT); CHECK(attribute, FAIL, "H5Acreate2"); /* Keep a copy of the attribute names around for later */ anames[i] = HDstrdup(name); CHECK(anames[i], NULL, "strdup"); ret = H5Aclose(attribute); CHECK(ret, FAIL, "H5Aclose"); } /* end for */ /* Close everything up */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); ret = H5Sclose(filespace); CHECK(ret, FAIL, "H5Sclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Iterate through the attributes on the dataset in various ways */ file = H5Fopen(DATAFILE, H5F_ACC_RDONLY, fapl); CHECK(file, FAIL, "H5Fopen"); dataset = H5Dopen2(file, "Dataset", H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dopen2"); /* Test invalid indices for starting iteration */ info.command = RET_ZERO; /* Test skipping exactly as many attributes as there are */ idx = NATTR; H5E_BEGIN_TRY { ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, &idx, aiter_cb, &info); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Aiterate2"); /* Test skipping more attributes than there are */ idx = NATTR + 1; H5E_BEGIN_TRY { ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, &idx, aiter_cb, &info); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Aiterate2"); /* Test all attributes on dataset, when callback always returns 0 */ info.command = RET_ZERO; idx = 0; if((ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, &idx, aiter_cb, &info)) > 0) TestErrPrintf("Attribute iteration function didn't return zero correctly!\n"); /* Test all attributes on dataset, when callback always returns 1 */ /* This also tests the "restarting" ability, because the index changes */ info.command = RET_TWO; idx = i = 0; while((ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, &idx, aiter_cb, &info)) > 0) { /* Verify return value from iterator gets propagated correctly */ VERIFY(ret, 2, "H5Aiterate2"); /* Increment the number of times "2" is returned */ i++; /* Verify that the index is the correct value */ VERIFY(idx, (unsigned)i, "H5Aiterate2"); /* Don't check name when new format is used */ if(!new_format) { /* Verify that the correct name is retrieved */ if(HDstrcmp(info.name, anames[(size_t)idx - 1]) != 0) TestErrPrintf("%u: Attribute iteration function didn't set names correctly, info.name = '%s', anames[%u] = '%s'!\n", __LINE__, info.name, (unsigned)(idx - 1), anames[(size_t)idx - 1]); } /* end if */ } /* end while */ VERIFY(ret, -1, "H5Aiterate2"); if(i != 50 || idx != 50) TestErrPrintf("%u: Attribute iteration function didn't perform multiple iterations correctly!\n", __LINE__); /* Test all attributes on dataset, when callback changes return value */ /* This also tests the "restarting" ability, because the index changes */ info.command = new_format ? RET_CHANGE2 : RET_CHANGE; idx = i = 0; while((ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, &idx, aiter_cb, &info)) > 0) { /* Verify return value from iterator gets propagated correctly */ VERIFY(ret, 1, "H5Aiterate2"); /* Increment the number of times "1" is returned */ i++; /* Verify that the index is the correct value */ VERIFY(idx, (unsigned)i + 10, "H5Aiterate2"); /* Don't check name when new format is used */ if(!new_format) { /* Verify that the correct name is retrieved */ if(HDstrcmp(info.name, anames[(size_t)idx - 1]) != 0) TestErrPrintf("%u: Attribute iteration function didn't set names correctly, info.name = '%s', anames[%u] = '%s'!\n", __LINE__, info.name, (unsigned)(idx - 1), anames[(size_t)idx - 1]); } /* end if */ } /* end while */ VERIFY(ret, -1, "H5Aiterate2"); if(i != 40 || idx != 50) TestErrPrintf("%u: Attribute iteration function didn't perform multiple iterations correctly!\n", __LINE__); ret=H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); ret=H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Free the attribute names */ for(i=0; i< NATTR; i++) HDfree(anames[i]); } /* test_iter_attr() */
herr_t H5IM_find_palette( hid_t loc_id ) { return H5Aiterate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, find_palette, NULL); }
int main (void) { hid_t file, dataset; /* File and dataset identifiers */ hid_t fid; /* Dataspace identifier */ hid_t attr1, attr2, attr3; /* Attribute identifiers */ hid_t attr; hid_t aid1, aid2, aid3; /* Attribute dataspace identifiers */ hid_t atype, atype_mem; /* Attribute type */ H5T_class_t type_class; hsize_t fdim[] = {SIZE}; hsize_t adim[] = {ADIM1, ADIM2}; /* Dimensions of the first attribute */ float matrix[ADIM1][ADIM2]; /* Attribute data */ herr_t ret; /* Return value */ H5O_info_t oinfo; /* Object info */ unsigned i, j; /* Counters */ char string_out[80]; /* Buffer to read string attribute back */ int point_out; /* Buffer to read scalar attribute back */ /* * Data initialization. */ int vector[] = {1, 2, 3, 4, 5, 6, 7}; /* Dataset data */ int point = 1; /* Value of the scalar attribute */ char string[] = "ABCD"; /* Value of the string attribute */ for (i=0; i < ADIM1; i++) { /* Values of the array attribute */ for (j=0; j < ADIM2; j++) matrix[i][j] = -1.; } /* * Create a file. */ file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); /* * Create the dataspace for the dataset in the file. */ fid = H5Screate(H5S_SIMPLE); ret = H5Sset_extent_simple(fid, RANK, fdim, NULL); /* * Create the dataset in the file. */ dataset = H5Dcreate2(file, "Dataset", H5T_NATIVE_INT, fid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); /* * Write data to the dataset. */ ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT, vector); /* * Create dataspace for the first attribute. */ aid1 = H5Screate(H5S_SIMPLE); ret = H5Sset_extent_simple(aid1, ARANK, adim, NULL); /* * Create array attribute. */ attr1 = H5Acreate2(dataset, ANAME, H5T_NATIVE_FLOAT, aid1, H5P_DEFAULT, H5P_DEFAULT); /* * Write array attribute. */ ret = H5Awrite(attr1, H5T_NATIVE_FLOAT, matrix); /* * Create scalar attribute. */ aid2 = H5Screate(H5S_SCALAR); attr2 = H5Acreate2(dataset, "Integer attribute", H5T_NATIVE_INT, aid2, H5P_DEFAULT, H5P_DEFAULT); /* * Write scalar attribute. */ ret = H5Awrite(attr2, H5T_NATIVE_INT, &point); /* * Create string attribute. */ aid3 = H5Screate(H5S_SCALAR); atype = H5Tcopy(H5T_C_S1); H5Tset_size(atype, 5); H5Tset_strpad(atype,H5T_STR_NULLTERM); attr3 = H5Acreate2(dataset, ANAMES, atype, aid3, H5P_DEFAULT, H5P_DEFAULT); /* * Write string attribute. */ ret = H5Awrite(attr3, atype, string); /* * Close attribute and file dataspaces, and datatype. */ ret = H5Sclose(aid1); ret = H5Sclose(aid2); ret = H5Sclose(aid3); ret = H5Sclose(fid); ret = H5Tclose(atype); /* * Close the attributes. */ ret = H5Aclose(attr1); ret = H5Aclose(attr2); ret = H5Aclose(attr3); /* * Close the dataset. */ ret = H5Dclose(dataset); /* * Close the file. */ ret = H5Fclose(file); /* * Reopen the file. */ file = H5Fopen(H5FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT); /* * Open the dataset. */ dataset = H5Dopen2(file, "Dataset", H5P_DEFAULT); /* * Attach to the scalar attribute using attribute name, then read and * display its value. */ attr = H5Aopen(dataset, "Integer attribute", H5P_DEFAULT); ret = H5Aread(attr, H5T_NATIVE_INT, &point_out); printf("The value of the attribute \"Integer attribute\" is %d \n", point_out); ret = H5Aclose(attr); /* * Find string attribute by iterating through all attributes */ ret = H5Oget_info(dataset, &oinfo); for(i = 0; i < (unsigned)oinfo.num_attrs; i++) { attr = H5Aopen_by_idx(dataset, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)i, H5P_DEFAULT, H5P_DEFAULT); atype = H5Aget_type(attr); type_class = H5Tget_class(atype); if (type_class == H5T_STRING) { atype_mem = H5Tget_native_type(atype, H5T_DIR_ASCEND); ret = H5Aread(attr, atype_mem, string_out); printf("Found string attribute; its index is %d , value = %s \n", i, string_out); ret = H5Tclose(atype_mem); } ret = H5Aclose(attr); ret = H5Tclose(atype); } /* * Get attribute info using iteration function. */ ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_info, NULL); /* * Close the dataset and the file. */ H5Dclose(dataset); H5Fclose(file); return 0; }