Skip to content

Commit

Permalink
Clarified error message when attributes are created on non-existing l…
Browse files Browse the repository at this point in the history
…inks
  • Loading branch information
DavidAce committed Jan 20, 2023
1 parent ec4c9aa commit 7182507
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 22 deletions.
2 changes: 1 addition & 1 deletion cmake/getExpandedTarget.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function(get_imported_location location target_name)
get_target_property(PROP_TYP ${target_name} TYPE)
if(PROP_IMP AND NOT PROP_TYP MATCHES "INTERFACE")
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
set(PROP_CFGS _${BUILD_TYPE};_${CMAKE_BUILD_TYPE};;)
set(PROP_CFGS _${BUILD_TYPE};_${CMAKE_BUILD_TYPE};"";)
set(PROP_VARS IMPORTED_LOCATION;LOCATION)
foreach(PROP_CFG ${PROP_CFGS})
foreach(PROP_VAR ${PROP_VARS})
Expand Down
5 changes: 2 additions & 3 deletions include/h5pp/details/h5ppFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,6 @@ namespace h5pp {
throw h5pp::runtime_error("Attempted to create attribute on read-only file [{}]", filePath.string());
if(attrInfo.hasLocId()) h5pp::scan::inferAttrInfo(attrInfo, attrInfo.getLocId(), options, plists);
else h5pp::scan::inferAttrInfo(attrInfo, openFileHandle(), options, plists);

h5pp::hdf5::createAttribute(attrInfo);
}

Expand Down Expand Up @@ -1000,15 +999,15 @@ namespace h5pp {
template<typename DataType>
void readAttribute(DataType &data, const h5pp::AttrInfo &attrInfo, const Options &options = Options()) const {
static_assert(not std::is_const_v<DataType>);
if(attrInfo.linkExists and not attrInfo.linkExists.value()) {
if(attrInfo.linkExists.has_value() and not attrInfo.linkExists.value()) {
throw h5pp::runtime_error("Could not read attribute [{}] in link [{}]: "
"Link does not exist. "
"NOTE: h5pp v1.10 and above requires the 'linkPath' argument before 'attrName'.",
attrInfo.attrName.value(),
attrInfo.linkPath.value());
}

if(attrInfo.attrExists and not attrInfo.attrExists.value()) {
if(attrInfo.attrExists.has_value() and not attrInfo.attrExists.value()) {
throw h5pp::runtime_error("Could not read attribute [{}] in link [{}]: "
"Attribute does not exist. "
"NOTE: h5pp v1.10 and above requires the 'linkPath' argument before 'attrName'.",
Expand Down
38 changes: 20 additions & 18 deletions include/h5pp/details/h5ppHdf5.h
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,12 @@ namespace h5pp::hdf5 {

inline void createAttribute(AttrInfo &attrInfo) {
// Here we create, or register, the attribute id and set its properties before writing data to it.
if(attrInfo.linkExists.has_value() and not attrInfo.linkExists.value()) {
throw h5pp::runtime_error("Could not create attribute [{}] in link [{}]: "
"Link does not exist.",
attrInfo.attrName.value(),
attrInfo.linkPath.value());
}
attrInfo.assertCreateReady();
if(attrInfo.attrExists and attrInfo.attrExists.value()) {
h5pp::logger::log->trace("No need to create attribute [{}] in link [{}]: exists already",
Expand Down Expand Up @@ -2191,25 +2197,21 @@ namespace h5pp::hdf5 {
if(H5Tis_variable_str(h5Type) > 0) {
// When H5T_VARIABLE, H5Dwrite function expects [const char **], which is what we get from vlenBuf.data()
dataPtr = reinterpret_cast<const void **>(vlenBuf.data());
} else {
if(vlenBuf.size() == 1) {
dataPtr = static_cast<const void *>(*vlenBuf.data());
} else {
if constexpr(type::sfinae::has_text_v<DataType> and type::sfinae::is_iterable_v<DataType>) {
// We have a fixed-size string array now. We have to copy the strings to a contiguous array.
// vlenBuf already contains the pointer to each string, and bytesPerStr should be the size of each string
// including null terminators
size_t bytesPerStr = H5Tget_size(h5Type); // This is the fixed-size of a string, not a char! Includes null term
tempBuf.resize(bytesPerStr * vlenBuf.size());
for(size_t i = 0; i < vlenBuf.size(); i++) {
auto offset = tempBuf.data() + static_cast<long>(i * bytesPerStr);
// Construct a view of the null-terminated character string, not including the null character.
auto view = std::string_view(vlenBuf[i]); // view.size() will not include null term here!
std::copy_n(std::begin(view), std::min(view.size(), bytesPerStr - 1), offset); // Do not copy null character
}
dataPtr = static_cast<const void *>(tempBuf.data());
}
} else if(vlenBuf.size() == 1) {
dataPtr = static_cast<const void *>(*vlenBuf.data());
} else if constexpr(type::sfinae::has_text_v<DataType> and type::sfinae::is_iterable_v<DataType>) {
// We have a fixed-size string array now. We have to copy the strings to a contiguous array.
// vlenBuf already contains the pointer to each string, and bytesPerStr should be the size of each string
// including null terminators
size_t bytesPerStr = H5Tget_size(h5Type); // This is the fixed-size of a string, not a char! Includes null term
tempBuf.resize(bytesPerStr * vlenBuf.size());
for(size_t i = 0; i < vlenBuf.size(); i++) {
auto offset = tempBuf.data() + static_cast<long>(i * bytesPerStr);
// Construct a view of the null-terminated character string, not including the null character.
auto view = std::string_view(vlenBuf[i]); // view.size() will not include null term here!
std::copy_n(std::begin(view), std::min(view.size(), bytesPerStr - 1), offset); // Do not copy null character
}
dataPtr = static_cast<const void *>(tempBuf.data());
}
}
return dataPtr;
Expand Down

0 comments on commit 7182507

Please sign in to comment.