Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/h5cpp/attribute/attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,52 @@ void Attribute::close()
}


// special overload for reading attributes into a std::string
void Attribute::read(std::string &data, bool trim) const
{
auto file_type = datatype();
if (file_type.get_class() == datatype::Class::String)
{
read(data, file_type, trim);
}
else
{
hdf5::datatype::DatatypeHolder mem_type_holder;
read(data, mem_type_holder.get<std::string>(), file_type, trim);
}
}


void Attribute::read(std::string &data, const datatype::Datatype &mem_type, bool trim) const
{
datatype::Datatype file_type = datatype();
read(data, mem_type, file_type, trim);
}


void Attribute::read(std::string &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type, bool trim) const
{
check_size(dataspace::create(data), dataspace(), "read");

if (file_type.get_class() == datatype::Class::String)
{
datatype::String string_type(file_type);

if (string_type.is_variable_length())
{
read_variable_length_string(data, mem_type);
}
else
{
read_fixed_length_string(data, mem_type, trim);
}
}
else
{
read_contiguous_data(data, mem_type);
}
}


} // namespace attribute
} // namespace hdf5
33 changes: 32 additions & 1 deletion src/h5cpp/attribute/attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,19 @@ class DLL_EXPORT Attribute
template<typename T>
void read(T &data,const datatype::Datatype &mem_type) const;

void read(std::string &data, bool trim = false) const;

void read(std::string &data, const datatype::Datatype &mem_type, bool trim = false) const;

private:
node::Link parent_link_;
ObjectHandle handle_;

template<typename T>
void read(T &data,const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const;

void read(std::string &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type, bool trim = false) const;

template<typename T>
void write_fixed_length_string(const T &data,
const datatype::Datatype &mem_type) const
Expand Down Expand Up @@ -273,7 +279,32 @@ class DLL_EXPORT Attribute

}

template<typename T>
void read_fixed_length_string(std::string &data,
const datatype::Datatype &mem_type, bool trim = false) const
{
using Trait = FixedLengthStringTrait<std::string>;
using SpaceTrait = hdf5::dataspace::TypeTrait<std::string>;

auto buffer = Trait::BufferType::create(mem_type, SpaceTrait::create(data));

if (H5Aread(static_cast<hid_t>(handle_),
static_cast<hid_t>(mem_type),
buffer.data()) < 0)
{
error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
}

if (trim)
{
data = Trait::from_buffer_trimmed(buffer, mem_type, SpaceTrait::create(data));
}
else
{
data = Trait::from_buffer(buffer, mem_type, SpaceTrait::create(data));
}
}

template <typename T>
void read_variable_length_string(T &data,
const datatype::Datatype &mem_type) const
{
Expand Down
38 changes: 37 additions & 1 deletion src/h5cpp/core/fixed_length_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
//
#pragma once

#include <algorithm>
#include <vector>
#include <string>
#include <h5cpp/dataspace/dataspace.hpp>
Expand Down Expand Up @@ -120,7 +121,42 @@ struct FixedLengthStringTrait<std::string>
const datatype::String &,
const dataspace::Dataspace &)
{
return DataType(buffer.begin(),buffer.end());
return DataType(buffer.begin(), buffer.end());
}

//!
//! @brief store data from buffer in target memory and trim any tailing null-terminating characters
//!
//! @param buffer reference to the IO buffer
//! @param memory_type the datatype describing how the string is stored in the file
//! @return new data instance
static DataType from_buffer_trimmed(const BufferType &buffer,
const datatype::String &memory_type,
const dataspace::Dataspace &)
{
const auto padding = memory_type.padding();
auto end_it = buffer.end();
switch (padding)
{
case datatype::StringPad::NullTerm:
end_it = std::find(buffer.begin(), buffer.end(), '\0');
break;
case datatype::StringPad::NullPad:
// get iterator to last padding \0 character
end_it = std::find_if_not(buffer.rbegin(), buffer.rend(), [](const BufferType::value_type &c)
{ return c == '\0'; })
.base();
break;
case datatype::StringPad::SpacePad:
// get iterator to last padding space character
end_it = std::find_if_not(buffer.rbegin(), buffer.rend(), [](const BufferType::value_type &c)
{ return c == ' '; })
.base();
break;
default:
break;
}
return DataType(buffer.begin(), end_it);
}
};

Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include_directories(${PROJECT_SOURCE_DIR}/src

configure_file(h5py_test_data.h5 h5py_test_data.h5 COPYONLY)
configure_file(h5py_test_boolattr.h5 h5py_test_boolattr.h5 COPYONLY)
configure_file(h5py_test_string_attributes.h5 h5py_test_string_attributes.h5 COPYONLY)
configure_file(pniio_test_boolattr.h5 pniio_test_boolattr.h5 COPYONLY)

include_directories(${CMAKE_CURRENT_SOURCE_DIR})
Expand Down
3 changes: 2 additions & 1 deletion test/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

set(test_sources
set(test_sources
ObjectHandleDefault.cpp
object_handle_test.cpp
file_object_handle_test.cpp
Expand All @@ -10,6 +10,7 @@ set(test_sources
attribute_object_handle_test.cpp
property_objects_handle_test.cpp
error_objects_handle_test.cpp
fixed_length_string_test.cpp
test_environment.cpp
iteration_index_test.cpp
iteration_order_test.cpp
Expand Down
Loading
Loading