inline typename boost::enable_if<boost::is_same<T, std::string>, T>::type read_attribute(H5::H5Object const& object, std::string const& name) { H5::Attribute attr; try { H5XX_NO_AUTO_PRINT(H5::AttributeIException); attr = object.openAttribute(name); } catch (H5::AttributeIException const&) { throw; } if (!has_scalar_space(attr)) { throw H5::AttributeIException("H5::attribute::as", "incompatible dataspace"); } H5::DataType tid = attr.getDataType(); std::string value; if (!tid.isVariableStr()) { // read fixed-size string, allocate space in advance and let the HDF5 // library take care about NULLTERM and NULLPAD strings value.resize(tid.getSize(), std::string::value_type()); attr.read(tid, &*value.begin()); } else { // read variable-length string, memory will be allocated by HDF5 C // library and must be freed by us char *c_str; if (H5Aread(attr.getId(), tid.getId(), &c_str) < 0) { throw H5::AttributeIException("Attribute::read", "H5Aread failed"); } value = c_str; // copy '\0'-terminated string free(c_str); } return value; }
inline typename boost::enable_if<boost::mpl::and_< is_vector<T> , boost::is_same<typename T::value_type, std::string> >, T>::type read_attribute(H5::H5Object const& object, std::string const& name) { H5::Attribute attr; try { H5XX_NO_AUTO_PRINT(H5::AttributeIException); attr = object.openAttribute(name); } catch (H5::AttributeIException const&) { throw; } H5::DataSpace ds(attr.getSpace()); if (!ds.isSimple()) { throw H5::AttributeIException("H5::attribute::as", "incompatible dataspace"); } size_t size = ds.getSimpleExtentNpoints(); H5::DataType tid = attr.getDataType(); if (tid.isVariableStr()) { throw error("reading non-scalar attribute of variable-length strings not supported"); } size_t str_len = tid.getSize(); // read to contiguous buffer and copy to std::vector std::vector<char> buffer(str_len * size); attr.read(tid, &*buffer.begin()); T value; value.reserve(size); char const* s = buffer.data(); for (size_t i = 0; i < size; ++i, s += str_len) { size_t len = strnlen(s, str_len); // strings of str_len size are not '\0'-terminated value.push_back(std::string(s, len)); // copy len bytes from buffer } return value; }