Example #1
0
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;
}
Example #2
0
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;
}