From ee0fa5c1af78d3cb0269062379715de5ee89cc01 Mon Sep 17 00:00:00 2001 From: Andrej Babic Date: Tue, 16 Jan 2018 15:55:27 +0100 Subject: [PATCH] Dataset writing logic --- src/h5_utils.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++-- src/h5_utils.hpp | 16 +++++----- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/src/h5_utils.cpp b/src/h5_utils.cpp index e6e4c7f..3a4f802 100644 --- a/src/h5_utils.cpp +++ b/src/h5_utils.cpp @@ -12,6 +12,83 @@ H5::Group h5_utils::create_group(H5::CommonFG& target, std::string name) return target.createGroup(name); } +boost::any h5_utils::get_value_from_reference(string& dataset_name, boost::any value_reference, map& values) +{ + try { + auto reference_string = boost::any_cast(value_reference); + return values.at(reference_string); + + } catch (const boost::bad_any_cast& exception) { + stringstream error_message; + error_message << "Cannot convert dataset " << dataset_name << " value reference to string." << endl; + + throw runtime_error(error_message.str()); + + } catch (const out_of_range& exception){ + stringstream error_message; + error_message << "Dataset " << dataset_name << " value reference " << boost::any_cast(value_reference) << " not present in values map." << endl; + + throw runtime_error(error_message.str()); + } +} + +H5::DataSet h5_utils::write_dataset(H5::Group& target, h5_dataset& dataset, map& values){ + string name = dataset.name; + boost::any value; + + // Value is stored directly in the struct. + if (dataset.data_location == IMMEDIATE){ + value = dataset.value; + // Value in struct is just a string reference to into the values map. + } else { + value = h5_utils::get_value_from_reference(name, dataset.value, values); + } + + if (dataset.data_type == NX_CHAR) { + // Attempt to convert to const char * (string "literals" cause that). + try { + return h5_utils::write_dataset(target, name, string(boost::any_cast(value))); + } catch (const boost::bad_any_cast& exception) {} + + // Atempt to convert to string. + try { + return h5_utils::write_dataset(target, name, boost::any_cast(value)); + } catch (const boost::bad_any_cast& exception) {} + + // We cannot really convert this attribute. + stringstream error_message; + error_message << "Cannot convert dataset " << name << " to string or const char*." << endl; + + throw runtime_error(error_message.str()); + + } else if (dataset.data_type == NX_INT) { + try { + return h5_utils::write_dataset(target, name, boost::any_cast(value)); + } catch (const boost::bad_any_cast& exception) {} + + // We cannot really convert this attribute. + stringstream error_message; + error_message << "Cannot convert dataset " << name << " to INT." << endl; + + throw runtime_error(error_message.str()); + } else if (dataset.data_type == NX_FLOAT) { + try { + return h5_utils::write_dataset(target, name, boost::any_cast(value)); + } catch (const boost::bad_any_cast& exception) {} + + // We cannot really convert this attribute. + stringstream error_message; + error_message << "Cannot convert dataset " << name << " to INT." << endl; + + throw runtime_error(error_message.str()); + } else { + stringstream error_message; + error_message << "Unsupported dataset type for dataset " << name << "." << endl; + + throw runtime_error(error_message.str()); + } +} + H5::DataSet h5_utils::write_dataset(H5::Group& target, string name, double value) { H5::DataSpace att_space(H5S_SCALAR); @@ -63,15 +140,17 @@ void h5_utils::write_attribute(H5::H5Object& target, string name, int value) h5_attribute.write(data_type, &value); } -void h5_utils::write_attribute(H5::H5Object& target, h5_attr& attribute) +void h5_utils::write_attribute(H5::H5Object& target, h5_attr& attribute, map& values) { string name = attribute.name; boost::any value; + // Value is stored directly in the struct. if (attribute.data_location == IMMEDIATE){ value = attribute.value; + // Value in struct is just a string reference to into the values map. } else { - // TODO: Implement value. + value = h5_utils::get_value_from_reference(name, attribute.value, values); } if (attribute.data_type == NX_CHAR) { diff --git a/src/h5_utils.hpp b/src/h5_utils.hpp index e05df29..a8e99ce 100644 --- a/src/h5_utils.hpp +++ b/src/h5_utils.hpp @@ -5,6 +5,7 @@ #include #include #include +#include typedef boost::any h5_value; @@ -43,16 +44,16 @@ struct h5_data_base{ }; struct h5_parent: public h5_base{ - h5_parent(std::string name, NODE_TYPE node_type, std::list items) : h5_base(name, node_type), items(items) {}; - std::list items; + h5_parent(std::string name, NODE_TYPE node_type, std::list items) : h5_base(name, node_type), items(items) {}; + std::list items; }; struct h5_group : public h5_parent { - h5_group(std::string name, std::list items) : h5_parent(name, GROUP, items) {}; + h5_group(std::string name, std::list items) : h5_parent(name, GROUP, items) {}; }; struct h5_dataset : public h5_parent, public h5_data_base{ - h5_dataset(std::string name, std::string value, DATA_TYPE data_type, std::list items={}) + h5_dataset(std::string name, std::string value, DATA_TYPE data_type, std::list items={}) : h5_parent(name, DATASET, items), h5_data_base(data_type, REFERENCE), value(value) {}; std::string value; @@ -67,17 +68,16 @@ struct h5_attr : public h5_base, public h5_data_base { namespace h5_utils{ H5::Group create_group(H5::CommonFG& target, std::string name); - H5::DataSet write_dataset(H5::Group& target, h5_dataset& dataset); - + H5::DataSet write_dataset(H5::Group& target, h5_dataset& dataset, std::map& values); H5::DataSet write_dataset(H5::Group& target, std::string name, double value); H5::DataSet write_dataset(H5::Group& target, std::string name, int value); H5::DataSet write_dataset(H5::Group& target, std::string name, std::string value); - void write_attribute(H5::H5Object& target, h5_attr& attribute); + void write_attribute(H5::H5Object& target, h5_attr& attribute, std::map& values); void write_attribute(H5::H5Object& target, std::string name, std::string value); void write_attribute(H5::H5Object& target, std::string name, int value); - + boost::any get_value_from_reference(std::string& dataset_name, boost::any value_reference, std::map& values); } #endif \ No newline at end of file