From 955053bba4cbf067ba9d61c7edb2b08965a3800d Mon Sep 17 00:00:00 2001 From: Kerstin Keller Date: Thu, 26 Oct 2023 17:02:15 +0200 Subject: [PATCH 1/4] [measurement] Measurement Reader / Writer interface to expose Get/Set of DatatypeInformation as atomic operation. --- app/meas_cutter/src/measurement_exporter.cpp | 9 ++-- app/meas_cutter/src/measurement_importer.cpp | 13 +++--- app/meas_cutter/src/measurement_importer.h | 2 +- .../play_core/src/measurement_container.cpp | 14 +++--- .../play_core/src/measurement_container.h | 4 +- .../include/rec_client_core/topic_info.h | 44 ++++++++++++++++--- .../src/job/hdf5_writer_thread.cpp | 4 +- .../rec_client_core/src/monitoring_thread.cpp | 12 ++--- contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h | 3 ++ .../include/ecal/measurement/base/reader.h | 14 ++---- .../include/ecal/measurement/base/types.h | 23 ++++++++++ .../include/ecal/measurement/base/writer.h | 16 +++---- .../include/ecal/measurement/omeasurement.h | 7 ++- .../include/ecal/measurement/hdf5/reader.h | 13 +----- .../include/ecal/measurement/hdf5/writer.h | 16 +++---- contrib/measurement/hdf5/src/reader.cpp | 37 +++++++++++++--- contrib/measurement/hdf5/src/writer.cpp | 24 +++++++--- contrib/message/include/ecal/msg/message.h | 4 ++ .../message/include/ecal/msg/proto/message.h | 8 +++- .../message/include/ecal/msg/string/message.h | 9 +++- 20 files changed, 183 insertions(+), 93 deletions(-) diff --git a/app/meas_cutter/src/measurement_exporter.cpp b/app/meas_cutter/src/measurement_exporter.cpp index 909be8bbf0..32743aac5f 100644 --- a/app/meas_cutter/src/measurement_exporter.cpp +++ b/app/meas_cutter/src/measurement_exporter.cpp @@ -54,15 +54,18 @@ MeasurementExporter::~MeasurementExporter() void MeasurementExporter::createChannel(const std::string& channel_name, const eCALMeasCutterUtils::ChannelInfo& channel_info) { _current_channel_name = channel_name; + eCAL::experimental::measurement::base::DataTypeInformation data_type_info; if (channel_info.format == eCALMeasCutterUtils::SerializationFormat::PROTOBUF) { - _writer->SetChannelType(channel_name, "proto:" + channel_info.type); + data_type_info.encoding = "proto"; } else { - _writer->SetChannelType(channel_name, channel_info.type); + data_type_info.encoding = ""; } - _writer->SetChannelDescription(channel_name, channel_info.description); + data_type_info.name = channel_info.type; + data_type_info.descriptor = channel_info.description; + _writer->SetChannelDataTypeInformation(channel_name, data_type_info); } void MeasurementExporter::setData(eCALMeasCutterUtils::Timestamp timestamp, const eCALMeasCutterUtils::MetaData& meta_data, const std::string& payload) diff --git a/app/meas_cutter/src/measurement_importer.cpp b/app/meas_cutter/src/measurement_importer.cpp index 717acd3649..b38a8194a7 100644 --- a/app/meas_cutter/src/measurement_importer.cpp +++ b/app/meas_cutter/src/measurement_importer.cpp @@ -67,17 +67,17 @@ void MeasurementImporter::openChannel(const std::string& channel_name) _current_opened_channel_data._timestamps.clear(); _current_opened_channel_data._timestamp_entry_info_map.clear(); - if (isProtoChannel(_reader->GetChannelType(channel_name))) + auto channel_information = _reader->GetChannelDataTypeInformation(channel_name); + if (isProtoChannel(channel_information)) { _current_opened_channel_data._channel_info.format = eCALMeasCutterUtils::SerializationFormat::PROTOBUF; - _current_opened_channel_data._channel_info.type = _reader->GetChannelType(channel_name).substr(6); // remove "proto:" from type string } else { _current_opened_channel_data._channel_info.format = eCALMeasCutterUtils::SerializationFormat::UNKNOWN; - _current_opened_channel_data._channel_info.type = _reader->GetChannelType(channel_name); } - _current_opened_channel_data._channel_info.description = _reader->GetChannelDescription(channel_name); + _current_opened_channel_data._channel_info.type = channel_information.name; + _current_opened_channel_data._channel_info.description = channel_information.descriptor; _current_opened_channel_data._channel_info.name = channel_name; eCAL::experimental::measurement::base::EntryInfoSet entry_info_set; @@ -177,10 +177,9 @@ bool MeasurementImporter::isEcalMeasFile(const std::string& path) return false; } -bool MeasurementImporter::isProtoChannel(const std::string& channel_type) +bool MeasurementImporter::isProtoChannel(const eCAL::experimental::measurement::base::DataTypeInformation& channel_info) { - std::string space = channel_type.substr(0, channel_type.find_first_of(':')); - return (space.compare("proto") == 0); + return (channel_info.encoding.compare("proto") == 0); } std::string MeasurementImporter::getLoadedPath() diff --git a/app/meas_cutter/src/measurement_importer.h b/app/meas_cutter/src/measurement_importer.h index 6f1c348f87..0c20f3f5af 100644 --- a/app/meas_cutter/src/measurement_importer.h +++ b/app/meas_cutter/src/measurement_importer.h @@ -52,7 +52,7 @@ class MeasurementImporter private: bool isEcalMeasFile(const std::string& path); - bool isProtoChannel(const std::string& channel_type); + bool isProtoChannel(const eCAL::experimental::measurement::base::DataTypeInformation& channel_info); std::unique_ptr _reader; eCALMeasCutterUtils::ChannelData _current_opened_channel_data; std::string _loaded_path; diff --git a/app/play/play_core/src/measurement_container.cpp b/app/play/play_core/src/measurement_container.cpp index d95de520b4..fd509cc14e 100644 --- a/app/play/play_core/src/measurement_container.cpp +++ b/app/play/play_core/src/measurement_container.cpp @@ -129,10 +129,12 @@ void MeasurementContainer::CreatePublishers(const std::mapGetChannelType(channel_mapping.first); - auto topic_description = hdf5_meas_->GetChannelDescription(channel_mapping.first); - - publisher_map_.emplace(channel_mapping.first, PublisherInfo(channel_mapping.second, topic_type, topic_description)); + auto topic_info = hdf5_meas_->GetChannelDataTypeInformation(channel_mapping.first); + eCAL::SDataTypeInformation data_type_info; + data_type_info.name = topic_info.name; + data_type_info.encoding = topic_info.encoding; + data_type_info.descriptor = topic_info.descriptor; + publisher_map_.emplace(channel_mapping.first, PublisherInfo(channel_mapping.second, data_type_info)); } // Assign publishers to entries @@ -307,7 +309,9 @@ double MeasurementContainer::GetMaxTimestampOfChannel(const std::string& channel std::string MeasurementContainer::GetChannelType(const std::string& channel_name) const { - return hdf5_meas_->GetChannelType(channel_name); + // This function needs to also return the proper datatypes information! To clean up. + auto datatype_information = hdf5_meas_->GetChannelDataTypeInformation(channel_name); + return eCAL::Util::CombinedTopicEncodingAndType(datatype_information.encoding, datatype_information.name); } size_t MeasurementContainer::GetChannelCumulativeEstimatedSize(const std::string& channel_name) const diff --git a/app/play/play_core/src/measurement_container.h b/app/play/play_core/src/measurement_container.h index 690af019d8..66f47fa5a2 100644 --- a/app/play/play_core/src/measurement_container.h +++ b/app/play/play_core/src/measurement_container.h @@ -92,8 +92,8 @@ class MeasurementContainer eCAL::CPublisher publisher_; long long message_counter_; - PublisherInfo(const std::string& topic_name, const std::string& topic_type = "", const std::string& topic_description = "") - : publisher_(topic_name, topic_type, topic_description) + PublisherInfo(const std::string& topic_name, eCAL::SDataTypeInformation info_) + : publisher_(topic_name, info_) , message_counter_(0) {} }; diff --git a/app/rec/rec_client_core/include/rec_client_core/topic_info.h b/app/rec/rec_client_core/include/rec_client_core/topic_info.h index aa7b7d3b6f..ad50ac15e6 100644 --- a/app/rec/rec_client_core/include/rec_client_core/topic_info.h +++ b/app/rec/rec_client_core/include/rec_client_core/topic_info.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace eCAL { @@ -29,17 +30,48 @@ namespace eCAL { struct TopicInfo { - TopicInfo(const std::string& type, const std::string& description) - : type_(type), description_(description), description_quality_(0) + TopicInfo(const eCAL::SDataTypeInformation& tinfo) + : tinfo_(tinfo) {} + + TopicInfo(const std::string& type, const std::string& encoding, const std::string& description) + : tinfo_{ type, encoding, description } + {} + TopicInfo() - : description_quality_(0) {} - std::string type_; - std::string description_; + eCAL::SDataTypeInformation tinfo_; + + // This should be removed once internally SDatatypeInformation is saved alongside with the publisher ID.. + std::string GetLegacyType() + { + if (tinfo_.encoding.empty()) + { + return tinfo_.name; + } + else + { + return tinfo_.encoding + ":" + tinfo_.name; + } + } + + void SetLegacyType(const std::string& combined_topic_type_) + { + auto pos = combined_topic_type_.find(':'); + if (pos == std::string::npos) + { + tinfo_.encoding = ""; + tinfo_.name = combined_topic_type_; + } + else + { + tinfo_.encoding = combined_topic_type_.substr(0, pos); + tinfo_.name = combined_topic_type_.substr(pos + 1); + } + } - int description_quality_; + int description_quality_ = 0; std::map> publishers_; }; diff --git a/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp b/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp index c3ddd4902f..1d446513f6 100644 --- a/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp +++ b/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp @@ -169,8 +169,8 @@ namespace eCAL for (const auto& topic : topic_info_map_to_set) { - hdf5_writer_->SetChannelType(topic.first, topic.second.type_); - hdf5_writer_->SetChannelDescription(topic.first, topic.second.description_); + eCAL::experimental::measurement::base::DataTypeInformation topic_info{ topic.second.tinfo_.name, topic.second.tinfo_.encoding, topic.second.tinfo_.descriptor }; + hdf5_writer_->SetChannelDataTypeInformation(topic.first, topic_info); } } else if (frame) diff --git a/app/rec/rec_client_core/src/monitoring_thread.cpp b/app/rec/rec_client_core/src/monitoring_thread.cpp index af1fae8b06..d655d11fbd 100644 --- a/app/rec/rec_client_core/src/monitoring_thread.cpp +++ b/app/rec/rec_client_core/src/monitoring_thread.cpp @@ -84,7 +84,7 @@ namespace eCAL if (topic_info_map_it == topic_info_map_.end()) { // Create a new topic entry - topic_info_map_.emplace(topic.tname(), eCAL::rec::TopicInfo("", "")); + topic_info_map_.emplace(topic.tname(), eCAL::rec::TopicInfo("", "", "")); topic_info_map_it = topic_info_map_.find(topic.tname()); } @@ -166,18 +166,18 @@ namespace eCAL if ((channel_descriptor_entry_it != channel_descriptor_map.end()) && (channel_descriptor_entry_it->second.first >= topic_info_map_entry.second.description_quality_)) { - topic_info_map_entry.second.type_ = channel_descriptor_entry_it->second.second.first; - topic_info_map_entry.second.description_ = channel_descriptor_entry_it->second.second.second; + topic_info_map_entry.second.SetLegacyType(channel_descriptor_entry_it->second.second.first); + topic_info_map_entry.second.tinfo_.descriptor = channel_descriptor_entry_it->second.second.second; topic_info_map_entry.second.description_quality_ = channel_descriptor_entry_it->second.first; } - if (!topic_info_map_entry.second.type_.empty()) + if (!topic_info_map_entry.second.GetLegacyType().empty()) { - auto type_descriptor_entry_it = type_descriptor_map.find(topic_info_map_entry.second.type_); + auto type_descriptor_entry_it = type_descriptor_map.find(topic_info_map_entry.second.GetLegacyType()); if ((type_descriptor_entry_it != type_descriptor_map.end()) && (type_descriptor_entry_it->second.first >= topic_info_map_entry.second.description_quality_)) { - topic_info_map_entry.second.description_ = type_descriptor_entry_it->second.second; + topic_info_map_entry.second.tinfo_.descriptor = type_descriptor_entry_it->second.second; topic_info_map_entry.second.description_quality_ = type_descriptor_entry_it->second.first; } } diff --git a/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h b/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h index 848f640c0a..44c45cbedd 100644 --- a/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h +++ b/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h @@ -214,6 +214,9 @@ namespace eCAL **/ void SetChannelType(const std::string& channel_name, const std::string& type); + + + /** * @brief Gets minimum timestamp for specified channel * diff --git a/contrib/measurement/base/include/ecal/measurement/base/reader.h b/contrib/measurement/base/include/ecal/measurement/base/reader.h index 521ece05f1..557b94d887 100644 --- a/contrib/measurement/base/include/ecal/measurement/base/reader.h +++ b/contrib/measurement/base/include/ecal/measurement/base/reader.h @@ -126,22 +126,14 @@ namespace eCAL virtual bool HasChannel(const std::string& channel_name) const = 0; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - virtual std::string GetChannelDescription(const std::string& channel_name) const = 0; - - /** - * @brief Gets the channel type of the given channel + * @brief Get data type information of the given channel * * @param channel_name channel name * * @return channel type **/ - virtual std::string GetChannelType(const std::string& channel_name) const = 0; + virtual DataTypeInformation GetChannelDataTypeInformation(const std::string & channel_name) const = 0; + /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/measurement/base/include/ecal/measurement/base/types.h b/contrib/measurement/base/include/ecal/measurement/base/types.h index 34fa97b6cd..0906824716 100644 --- a/contrib/measurement/base/include/ecal/measurement/base/types.h +++ b/contrib/measurement/base/include/ecal/measurement/base/types.h @@ -36,6 +36,29 @@ namespace eCAL { namespace base { + /** + * @brief Optional compile time information associated with a given topic + * (necessary for reflection / runtime type checking) + **/ + struct DataTypeInformation + { + std::string name; //!< name of the datatype + std::string encoding; //!< encoding of the datatype (e.g. protobuf, flatbuffers, capnproto) + std::string descriptor; //!< descriptor information of the datatype (necessary for reflection) + + //!< @cond + bool operator==(const DataTypeInformation& other) const + { + return name == other.name && encoding == other.encoding && descriptor == other.descriptor; + } + + bool operator!=(const DataTypeInformation& other) const + { + return !(*this == other); + } + //!< @endcond + }; + /** * @brief Info struct for a single measurement entry **/ diff --git a/contrib/measurement/base/include/ecal/measurement/base/writer.h b/contrib/measurement/base/include/ecal/measurement/base/writer.h index 72fff0a07b..9eb003290c 100644 --- a/contrib/measurement/base/include/ecal/measurement/base/writer.h +++ b/contrib/measurement/base/include/ecal/measurement/base/writer.h @@ -139,20 +139,14 @@ namespace eCAL virtual void SetOneFilePerChannelEnabled(bool enabled) = 0; /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel - **/ - virtual void SetChannelDescription(const std::string& channel_name, const std::string& description) = 0; - - /** - * @brief Set type of the given channel + * @brief Set data type information of the given channel * * @param channel_name channel name - * @param type type of the channel + * @param info datatype info of the channel + * + * @return channel type **/ - virtual void SetChannelType(const std::string& channel_name, const std::string& type) = 0; + virtual void SetChannelDataTypeInformation(const std::string & channel_name, const DataTypeInformation& info) = 0; /** * @brief Set measurement file base name (desired name for the actual hdf5 files that will be created) diff --git a/contrib/measurement/base/include/ecal/measurement/omeasurement.h b/contrib/measurement/base/include/ecal/measurement/omeasurement.h index a75d2780fa..ca835d9474 100644 --- a/contrib/measurement/base/include/ecal/measurement/omeasurement.h +++ b/contrib/measurement/base/include/ecal/measurement/omeasurement.h @@ -132,8 +132,11 @@ namespace eCAL inline OChannel OMeasurement::Create(const std::string& channel) const { static T msg; - meas->SetChannelType(channel, eCAL::message::GetTypeName(msg)); - meas->SetChannelDescription(channel, eCAL::message::GetDescription(msg)); + eCAL::experimental::measurement::base::DataTypeInformation datatype_info; + datatype_info.name = eCAL::message::GetTypeName(msg); + datatype_info.encoding = eCAL::message::GetEncoding(msg); + datatype_info.descriptor = eCAL::message::GetDescription(msg); + meas->SetChannelDataTypeInformation(channel, datatype_info); // Construct a channel based return OChannel{meas, channel}; } diff --git a/contrib/measurement/hdf5/include/ecal/measurement/hdf5/reader.h b/contrib/measurement/hdf5/include/ecal/measurement/hdf5/reader.h index be27f56c10..c626b2efab 100644 --- a/contrib/measurement/hdf5/include/ecal/measurement/hdf5/reader.h +++ b/contrib/measurement/hdf5/include/ecal/measurement/hdf5/reader.h @@ -136,22 +136,13 @@ namespace eCAL bool HasChannel(const std::string& channel_name) const override; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - std::string GetChannelDescription(const std::string& channel_name) const override; - - /** - * @brief Gets the channel type of the given channel + * @brief Get data type information of the given channel * * @param channel_name channel name * * @return channel type **/ - std::string GetChannelType(const std::string& channel_name) const override; + base::DataTypeInformation GetChannelDataTypeInformation(const std::string& channel_name) const override; /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/measurement/hdf5/include/ecal/measurement/hdf5/writer.h b/contrib/measurement/hdf5/include/ecal/measurement/hdf5/writer.h index c7de047568..355bccc2e4 100644 --- a/contrib/measurement/hdf5/include/ecal/measurement/hdf5/writer.h +++ b/contrib/measurement/hdf5/include/ecal/measurement/hdf5/writer.h @@ -149,20 +149,14 @@ namespace eCAL void SetOneFilePerChannelEnabled(bool enabled) override; /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel - **/ - void SetChannelDescription(const std::string& channel_name, const std::string& description) override; - - /** - * @brief Set type of the given channel + * @brief Set data type information of the given channel * * @param channel_name channel name - * @param type type of the channel + * @param info datatype info of the channel + * + * @return channel type **/ - void SetChannelType(const std::string& channel_name, const std::string& type) override; + void SetChannelDataTypeInformation(const std::string& channel_name, const base::DataTypeInformation& info) override; /** * @brief Set measurement file base name (desired name for the actual hdf5 files that will be created) diff --git a/contrib/measurement/hdf5/src/reader.cpp b/contrib/measurement/hdf5/src/reader.cpp index 320e7308f9..67481e41a9 100644 --- a/contrib/measurement/hdf5/src/reader.cpp +++ b/contrib/measurement/hdf5/src/reader.cpp @@ -1,9 +1,31 @@ #include #include + using namespace eCAL::experimental::measurement::hdf5; using namespace eCAL::experimental::measurement; +namespace +{ + // To be removed soon-ish! + std::pair SplitCombinedTopicType(const std::string& combined_topic_type_) + { + auto pos = combined_topic_type_.find(':'); + if (pos == std::string::npos) + { + std::string encoding; + std::string type{ combined_topic_type_ }; + return std::make_pair(encoding, type); + } + else + { + std::string encoding = combined_topic_type_.substr(0, pos); + std::string type = combined_topic_type_.substr(pos + 1); + return std::make_pair(encoding, type); + } + } +} + Reader::Reader() : measurement(std::make_unique()) {} @@ -48,14 +70,15 @@ bool Reader::HasChannel(const std::string& channel_name) const return measurement->HasChannel(channel_name); } -std::string Reader::GetChannelDescription(const std::string& channel_name) const -{ - return measurement->GetChannelDescription(channel_name); -} - -std::string Reader::GetChannelType(const std::string& channel_name) const +base::DataTypeInformation Reader::GetChannelDataTypeInformation(const std::string& channel_name) const { - return measurement->GetChannelType(channel_name); + base::DataTypeInformation info; + auto type = measurement->GetChannelType(channel_name); + auto split_types = SplitCombinedTopicType(type); + info.encoding = split_types.first; + info.name = split_types.second; + info.descriptor = measurement->GetChannelDescription(channel_name); + return info; } long long Reader::GetMinTimestamp(const std::string& channel_name) const diff --git a/contrib/measurement/hdf5/src/writer.cpp b/contrib/measurement/hdf5/src/writer.cpp index e8cd2a1c38..d28eb0666d 100644 --- a/contrib/measurement/hdf5/src/writer.cpp +++ b/contrib/measurement/hdf5/src/writer.cpp @@ -4,6 +4,21 @@ using namespace eCAL::experimental::measurement::hdf5; using namespace eCAL::experimental::measurement; +namespace { + //To be removed soon - ish + std::string CombinedTopicEncodingAndType(const std::string & topic_encoding_, const std::string & topic_type_) + { + if (topic_encoding_.empty()) + { + return topic_type_; + } + else + { + return topic_encoding_ + ":" + topic_type_; + } + } +} + Writer::Writer() : measurement(std::make_unique()) {} @@ -53,14 +68,11 @@ void Writer::SetOneFilePerChannelEnabled(bool enabled) return measurement->SetOneFilePerChannelEnabled(enabled); } -void Writer::SetChannelDescription(const std::string& channel_name, const std::string& description) +void Writer::SetChannelDataTypeInformation(const std::string& channel_name, const base::DataTypeInformation& info) { - return measurement->SetChannelDescription(channel_name, description); -} -void Writer::SetChannelType(const std::string& channel_name, const std::string& type) -{ - return measurement->SetChannelType(channel_name, type); + measurement->SetChannelType(channel_name, CombinedTopicEncodingAndType(info.encoding, info.name)); + measurement->SetChannelDescription(channel_name, info.descriptor); } void Writer::SetFileBaseName(const std::string& base_name) diff --git a/contrib/message/include/ecal/msg/message.h b/contrib/message/include/ecal/msg/message.h index 96da5fbc39..9511a7669c 100644 --- a/contrib/message/include/ecal/msg/message.h +++ b/contrib/message/include/ecal/msg/message.h @@ -30,6 +30,10 @@ namespace eCAL //// unfortunately, we need an actual object for this :/ //template //std::string GetTypeName(const T& message); + + //// unfortunately, we need an actual object for this :/ + //template + //std::string GetEncoding(const T& message); //// unfortunately, we need an actual object for this :/ //template diff --git a/contrib/message/include/ecal/msg/proto/message.h b/contrib/message/include/ecal/msg/proto/message.h index e3520e863d..53b965f740 100644 --- a/contrib/message/include/ecal/msg/proto/message.h +++ b/contrib/message/include/ecal/msg/proto/message.h @@ -38,7 +38,13 @@ namespace eCAL // unfortunately, we need an actual object for this :/ inline std::string GetTypeName(const google::protobuf::Message& message) { - return("proto:" + message.GetTypeName()); + return(message.GetTypeName()); + } + + // unfortunately, we need an actual object for this :/ + inline std::string GetEncoding(const google::protobuf::Message& /*message*/) + { + return("proto"); } // unfortunately, we need an actual object for this :/ diff --git a/contrib/message/include/ecal/msg/string/message.h b/contrib/message/include/ecal/msg/string/message.h index 3aecef9406..3192aa6e79 100644 --- a/contrib/message/include/ecal/msg/string/message.h +++ b/contrib/message/include/ecal/msg/string/message.h @@ -30,15 +30,22 @@ namespace eCAL // unfortunately, we need an actual object for this :/ inline std::string GetTypeName(const std::string& /*message*/) { - return("base:std::string"); + return("std::string"); } + // unfortunately, we need an actual object for this :/ + inline std::string GetEncoding(const std::string& /*message*/) + { + return("base"); + } + // unfortunately, we need an actual object for this :/ inline std::string GetDescription(const std::string& /*message*/) { return(""); } + inline bool Serialize(const std::string& message, std::string& buffer) { buffer = message; From 965377e36f3dfb882eddc020976426839cde9adc Mon Sep 17 00:00:00 2001 From: Kerstin Keller Date: Tue, 30 Jan 2024 15:41:56 +0100 Subject: [PATCH 2/4] GetChannelDataTypeInformation and SetChannelDataTypeInformation in all of eh5. --- contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h | 22 ++++- contrib/ecalhdf5/include/ecalhdf5/eh5_types.h | 2 + contrib/ecalhdf5/src/eh5_meas.cpp | 41 +++++--- contrib/ecalhdf5/src/eh5_meas_dir.cpp | 40 +++----- contrib/ecalhdf5/src/eh5_meas_dir.h | 49 +++------ contrib/ecalhdf5/src/eh5_meas_file_v1.cpp | 24 ++--- contrib/ecalhdf5/src/eh5_meas_file_v1.h | 41 +++----- contrib/ecalhdf5/src/eh5_meas_file_v2.cpp | 28 +----- contrib/ecalhdf5/src/eh5_meas_file_v2.h | 41 +++----- .../ecalhdf5/src/eh5_meas_file_writer_v5.cpp | 20 ++-- .../ecalhdf5/src/eh5_meas_file_writer_v5.h | 41 +++----- contrib/ecalhdf5/src/eh5_meas_impl.h | 74 ++++++++------ contrib/measurement/hdf5/src/reader.cpp | 29 +----- contrib/measurement/hdf5/src/writer.cpp | 19 +--- .../ecalhdf5/hdf5_test/src/hdf5_test.cpp | 99 ++++++++++++++++++- 15 files changed, 281 insertions(+), 289 deletions(-) diff --git a/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h b/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h index 44c45cbedd..4b3c64df96 100644 --- a/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h +++ b/contrib/ecalhdf5/include/ecalhdf5/eh5_meas.h @@ -187,6 +187,7 @@ namespace eCAL * * @return channel description **/ + [[deprecated("Please use GetChannelDataTypeInformation instead")]] std::string GetChannelDescription(const std::string& channel_name) const; /** @@ -195,6 +196,7 @@ namespace eCAL * @param channel_name channel name * @param description description of the channel **/ + [[deprecated("Please use SetChannelDataTypeInformation instead")]] void SetChannelDescription(const std::string& channel_name, const std::string& description); /** @@ -204,6 +206,7 @@ namespace eCAL * * @return channel type **/ + [[deprecated("Please use GetChannelDataTypeInformation instead")]] std::string GetChannelType(const std::string& channel_name) const; /** @@ -212,10 +215,27 @@ namespace eCAL * @param channel_name channel name * @param type type of the channel **/ + [[deprecated("Please use SetChannelDataTypeInformation instead")]] void SetChannelType(const std::string& channel_name, const std::string& type); + /** + * @brief Get data type information of the given channel + * + * @param channel_name channel name + * + * @return channel type + **/ + DataTypeInformation GetChannelDataTypeInformation(const std::string& channel_name) const; - + /** + * @brief Set data type information of the given channel + * + * @param channel_name channel name + * @param info datatype info of the channel + * + * @return channel type + **/ + void SetChannelDataTypeInformation(const std::string& channel_name, const DataTypeInformation& info); /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/ecalhdf5/include/ecalhdf5/eh5_types.h b/contrib/ecalhdf5/include/ecalhdf5/eh5_types.h index 18332bb5fb..91351e56b5 100644 --- a/contrib/ecalhdf5/include/ecalhdf5/eh5_types.h +++ b/contrib/ecalhdf5/include/ecalhdf5/eh5_types.h @@ -49,6 +49,8 @@ namespace eCAL using eAccessType = eCAL::experimental::measurement::base::AccessType; using eCAL::experimental::measurement::base::RDONLY; using eCAL::experimental::measurement::base::CREATE; + + using eCAL::experimental::measurement::base::DataTypeInformation; //!< @endcond } // namespace eh5 } // namespace eCAL diff --git a/contrib/ecalhdf5/src/eh5_meas.cpp b/contrib/ecalhdf5/src/eh5_meas.cpp index ce70758905..28419814ce 100644 --- a/contrib/ecalhdf5/src/eh5_meas.cpp +++ b/contrib/ecalhdf5/src/eh5_meas.cpp @@ -233,41 +233,54 @@ bool eCAL::eh5::HDF5Meas::HasChannel(const std::string& channel_name) const return ret_val; } +// deprecated std::string eCAL::eh5::HDF5Meas::GetChannelDescription(const std::string& channel_name) const { - std::string ret_val; - if (hdf_meas_impl_) - { - ret_val = hdf_meas_impl_->GetChannelDescription(GetEscapedTopicname(channel_name)); - } - - return ret_val; + auto datatype_info = GetChannelDataTypeInformation(channel_name); + return datatype_info.descriptor; } +// deprecated void eCAL::eh5::HDF5Meas::SetChannelDescription(const std::string& channel_name, const std::string& description) { - if (hdf_meas_impl_) - { - hdf_meas_impl_->SetChannelDescription(GetEscapedTopicname(channel_name), description); - } + auto current_info = GetChannelDataTypeInformation(channel_name); + current_info.descriptor = description; + SetChannelDataTypeInformation(channel_name, current_info); } +// deprecated std::string eCAL::eh5::HDF5Meas::GetChannelType(const std::string& channel_name) const { std::string ret_val; + auto datatype_info = GetChannelDataTypeInformation(channel_name); + std::tie(ret_val, std::ignore) = FromInfo(datatype_info); + return ret_val; +} + +// deprecated +void eCAL::eh5::HDF5Meas::SetChannelType(const std::string& channel_name, const std::string& type) +{ + auto current_info = GetChannelDataTypeInformation(channel_name); + auto new_info = CreateInfo(type, current_info.descriptor); + SetChannelDataTypeInformation(channel_name, new_info); +} + +eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5Meas::GetChannelDataTypeInformation(const std::string& channel_name) const +{ + eCAL::eh5::DataTypeInformation ret_val; if (hdf_meas_impl_) { - ret_val = hdf_meas_impl_->GetChannelType(GetEscapedTopicname(channel_name)); + ret_val = hdf_meas_impl_->GetChannelDataTypeInformation(GetEscapedTopicname(channel_name)); } return ret_val; } -void eCAL::eh5::HDF5Meas::SetChannelType(const std::string& channel_name, const std::string& type) +void eCAL::eh5::HDF5Meas::SetChannelDataTypeInformation(const std::string& channel_name, const eCAL::eh5::DataTypeInformation& info) { if (hdf_meas_impl_) { - hdf_meas_impl_->SetChannelType(GetEscapedTopicname(channel_name), type); + hdf_meas_impl_->SetChannelDataTypeInformation(GetEscapedTopicname(channel_name), info); } } diff --git a/contrib/ecalhdf5/src/eh5_meas_dir.cpp b/contrib/ecalhdf5/src/eh5_meas_dir.cpp index d2750d3184..0e8263d5ff 100644 --- a/contrib/ecalhdf5/src/eh5_meas_dir.cpp +++ b/contrib/ecalhdf5/src/eh5_meas_dir.cpp @@ -196,44 +196,27 @@ bool eCAL::eh5::HDF5MeasDir::HasChannel(const std::string& channel_name) const return channels_info_.count(channel_name) != 0; } -std::string eCAL::eh5::HDF5MeasDir::GetChannelDescription(const std::string& channel_name) const +eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5MeasDir::GetChannelDataTypeInformation(const std::string& channel_name) const { - std::string ret_val; + eCAL::eh5::DataTypeInformation ret_val; const auto& found = channels_info_.find(channel_name); if (found != channels_info_.end()) { - ret_val = found->second.description; + ret_val = found->second.info; } return ret_val; } -void eCAL::eh5::HDF5MeasDir::SetChannelDescription(const std::string& channel_name, const std::string& description) +void eCAL::eh5::HDF5MeasDir::SetChannelDataTypeInformation(const std::string& channel_name, const eCAL::eh5::DataTypeInformation& info) { // Get an existing writer or create a new one auto file_writer_it = GetWriter(channel_name); - file_writer_it->second->SetChannelDescription(channel_name, description); -} - -std::string eCAL::eh5::HDF5MeasDir::GetChannelType(const std::string& channel_name) const -{ - std::string ret_val; - - const auto& found = channels_info_.find(channel_name); - - if (found != channels_info_.end()) - { - ret_val = found->second.type; - } - return ret_val; -} + file_writer_it->second->SetChannelDataTypeInformation(channel_name, info); -void eCAL::eh5::HDF5MeasDir::SetChannelType(const std::string& channel_name, const std::string& type) -{ - // Get an existing writer or create a new one - auto file_writer_it = GetWriter(channel_name); - file_writer_it->second->SetChannelType(channel_name, type); + // Let's save them in case we need to query them + channels_info_[channel_name] = ChannelInfo(info); } long long eCAL::eh5::HDF5MeasDir::GetMinTimestamp(const std::string& channel_name) const @@ -457,17 +440,18 @@ bool eCAL::eh5::HDF5MeasDir::OpenRX(const std::string& path, eAccessType access for (const auto& channel : channels) { auto escaped_name = GetEscapedTopicname(channel); - auto description = reader->GetChannelDescription(channel); + auto info = reader->GetChannelDataTypeInformation(channel); + // What exactly does that do? what are we overwriting? if (channels_info_.find(escaped_name) == channels_info_.end()) { - channels_info_[escaped_name] = ChannelInfo(reader->GetChannelType(channel), description); + channels_info_[escaped_name] = ChannelInfo(info); } else { - if (!description.empty()) + if (!info.descriptor.empty()) { - channels_info_[escaped_name].description = description; + channels_info_[escaped_name].info.descriptor = info.descriptor; } } diff --git a/contrib/ecalhdf5/src/eh5_meas_dir.h b/contrib/ecalhdf5/src/eh5_meas_dir.h index 30d2308970..f6287b3e9c 100644 --- a/contrib/ecalhdf5/src/eh5_meas_dir.h +++ b/contrib/ecalhdf5/src/eh5_meas_dir.h @@ -143,38 +143,23 @@ namespace eCAL bool HasChannel(const std::string& channel_name) const override; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - std::string GetChannelDescription(const std::string& channel_name) const override; - - /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel + * @brief Get data type information of the given channel + * + * @param channel_name channel name + * + * @return channel type **/ - void SetChannelDescription(const std::string& channel_name, const std::string& description) override; + DataTypeInformation GetChannelDataTypeInformation(const std::string& channel_name) const override; /** - * @brief Gets the channel type of the given channel - * - * @param channel_name channel name - * - * @return channel type - **/ - std::string GetChannelType(const std::string& channel_name) const override; - - /** - * @brief Set type of the given channel - * - * @param channel_name channel name - * @param type type of the channel + * @brief Set data type information of the given channel + * + * @param channel_name channel name + * @param info datatype info of the channel + * + * @return channel type **/ - void SetChannelType(const std::string& channel_name, const std::string& type) override; + void SetChannelDataTypeInformation(const std::string& channel_name, const DataTypeInformation& info) override; /** * @brief Gets minimum timestamp for specified channel @@ -280,14 +265,12 @@ namespace eCAL protected: struct ChannelInfo { - std::string type; - std::string description; + DataTypeInformation info; std::list files; ChannelInfo() = default; - ChannelInfo(const std::string& type_, const std::string& description_) - : type(type_) - , description(description_) + ChannelInfo(const DataTypeInformation& info_) + : info(info_) {} }; diff --git a/contrib/ecalhdf5/src/eh5_meas_file_v1.cpp b/contrib/ecalhdf5/src/eh5_meas_file_v1.cpp index 02fed6dbec..20d1381f1d 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_v1.cpp +++ b/contrib/ecalhdf5/src/eh5_meas_file_v1.cpp @@ -164,32 +164,22 @@ bool eCAL::eh5::HDF5MeasFileV1::HasChannel(const std::string& channel_name) cons return std::find(channels.cbegin(), channels.cend(), channel_name) != channels.end(); } -std::string eCAL::eh5::HDF5MeasFileV1::GetChannelDescription(const std::string& channel_name) const +eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5MeasFileV1::GetChannelDataTypeInformation(const std::string& channel_name) const { - std::string description; + std::string type; if (EcalUtils::String::Icompare(channel_name, channel_name_)) - GetAttributeValue(file_id_, kChnDescAttrTitle, description); - - return description; -} - -void eCAL::eh5::HDF5MeasFileV1::SetChannelDescription(const std::string& /*channel_name*/, const std::string& /*description*/) -{ - ReportUnsupportedAction(); -} + GetAttributeValue(file_id_, kChnTypeAttrTitle, type); -std::string eCAL::eh5::HDF5MeasFileV1::GetChannelType(const std::string& channel_name) const -{ - std::string type; + std::string description; if (EcalUtils::String::Icompare(channel_name, channel_name_)) - GetAttributeValue(file_id_, kChnTypeAttrTitle, type); + GetAttributeValue(file_id_, kChnDescAttrTitle, description); - return type; + return CreateInfo(type, description); } -void eCAL::eh5::HDF5MeasFileV1::SetChannelType(const std::string& /*channel_name*/, const std::string& /*type*/) +void eCAL::eh5::HDF5MeasFileV1::SetChannelDataTypeInformation(const std::string& /*channel_name*/, const eCAL::eh5::DataTypeInformation& /*info*/) { ReportUnsupportedAction(); } diff --git a/contrib/ecalhdf5/src/eh5_meas_file_v1.h b/contrib/ecalhdf5/src/eh5_meas_file_v1.h index 38cf339eb7..317733c80d 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_v1.h +++ b/contrib/ecalhdf5/src/eh5_meas_file_v1.h @@ -135,38 +135,23 @@ namespace eCAL bool HasChannel(const std::string& channel_name) const override; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - std::string GetChannelDescription(const std::string& channel_name) const override; - - /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel + * @brief Get data type information of the given channel + * + * @param channel_name channel name + * + * @return channel type **/ - void SetChannelDescription(const std::string& channel_name, const std::string& description) override; + DataTypeInformation GetChannelDataTypeInformation(const std::string& channel_name) const override; /** - * @brief Gets the channel type of the given channel - * - * @param channel_name channel name - * - * @return channel type - **/ - std::string GetChannelType(const std::string& channel_name) const override; - - /** - * @brief Set type of the given channel - * - * @param channel_name channel name - * @param type type of the channel + * @brief Set data type information of the given channel + * + * @param channel_name channel name + * @param info datatype info of the channel + * + * @return channel type **/ - void SetChannelType(const std::string& channel_name, const std::string& type) override; + void SetChannelDataTypeInformation(const std::string& channel_name, const DataTypeInformation& info) override; /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/ecalhdf5/src/eh5_meas_file_v2.cpp b/contrib/ecalhdf5/src/eh5_meas_file_v2.cpp index 008623edc3..a84b15c4ba 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_v2.cpp +++ b/contrib/ecalhdf5/src/eh5_meas_file_v2.cpp @@ -144,8 +144,9 @@ bool eCAL::eh5::HDF5MeasFileV2::HasChannel(const std::string& channel_name) cons return std::find(channels.cbegin(), channels.cend(), channel_name) != channels.end(); } -std::string eCAL::eh5::HDF5MeasFileV2::GetChannelDescription(const std::string& channel_name) const +eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5MeasFileV2::GetChannelDataTypeInformation(const std::string& channel_name) const { + std::string type; std::string description; if (this->IsOk()) @@ -153,38 +154,19 @@ std::string eCAL::eh5::HDF5MeasFileV2::GetChannelDescription(const std::string& auto dataset_id = H5Dopen(file_id_, channel_name.c_str(), H5P_DEFAULT); if (dataset_id >= 0) { + GetAttributeValue(dataset_id, kChnTypeAttrTitle, type); GetAttributeValue(dataset_id, kChnDescAttrTitle, description); H5Dclose(dataset_id); } } - return description; + return CreateInfo(type, description); } -void eCAL::eh5::HDF5MeasFileV2::SetChannelDescription(const std::string& /*channel_name*/, const std::string& /*description*/) +void eCAL::eh5::HDF5MeasFileV2::SetChannelDataTypeInformation(const std::string& /*channel_name*/, const eCAL::eh5::DataTypeInformation& /*info*/) { } -std::string eCAL::eh5::HDF5MeasFileV2::GetChannelType(const std::string& channel_name) const -{ - std::string type; - - if (this->IsOk()) - { - auto dataset_id = H5Dopen(file_id_, channel_name.c_str(), H5P_DEFAULT); - if (dataset_id >= 0) - { - GetAttributeValue(dataset_id, kChnTypeAttrTitle, type); - H5Dclose(dataset_id); - } - } - - return type; -} - -void eCAL::eh5::HDF5MeasFileV2::SetChannelType(const std::string& /*channel_name*/, const std::string& /*type*/) -{ -} long long eCAL::eh5::HDF5MeasFileV2::GetMinTimestamp(const std::string& channel_name) const { diff --git a/contrib/ecalhdf5/src/eh5_meas_file_v2.h b/contrib/ecalhdf5/src/eh5_meas_file_v2.h index 6385f4f9fc..63934f88cb 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_v2.h +++ b/contrib/ecalhdf5/src/eh5_meas_file_v2.h @@ -135,38 +135,23 @@ namespace eCAL bool HasChannel(const std::string& channel_name) const override; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - std::string GetChannelDescription(const std::string& channel_name) const override; - - /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel + * @brief Get data type information of the given channel + * + * @param channel_name channel name + * + * @return channel type **/ - void SetChannelDescription(const std::string& channel_name, const std::string& description) override; + DataTypeInformation GetChannelDataTypeInformation(const std::string& channel_name) const override; /** - * @brief Gets the channel type of the given channel - * - * @param channel_name channel name - * - * @return channel type - **/ - std::string GetChannelType(const std::string& channel_name) const override; - - /** - * @brief Set type of the given channel - * - * @param channel_name channel name - * @param type type of the channel + * @brief Set data type information of the given channel + * + * @param channel_name channel name + * @param info datatype info of the channel + * + * @return channel type **/ - void SetChannelType(const std::string& channel_name, const std::string& type) override; + void SetChannelDataTypeInformation(const std::string& channel_name, const DataTypeInformation& info) override; /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp b/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp index b96d8396b9..f1aa1584cf 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp +++ b/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp @@ -138,26 +138,18 @@ bool eCAL::eh5::HDF5MeasFileWriterV5::HasChannel(const std::string& /*channel_na return false; } -std::string eCAL::eh5::HDF5MeasFileWriterV5::GetChannelDescription(const std::string& /*channel_name*/) const -{ - // UNSUPPORTED FUNCTION - return ""; -} -void eCAL::eh5::HDF5MeasFileWriterV5::SetChannelDescription(const std::string& channel_name, const std::string& description) -{ - channels_[channel_name].Description = description; -} - -std::string eCAL::eh5::HDF5MeasFileWriterV5::GetChannelType(const std::string& /*channel_name*/) const +eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5MeasFileWriterV5::GetChannelDataTypeInformation(const std::string& channel_name) const { // UNSUPPORTED FUNCTION - return ""; + return eCAL::eh5::DataTypeInformation{}; } -void eCAL::eh5::HDF5MeasFileWriterV5::SetChannelType(const std::string& channel_name, const std::string& type) +void eCAL::eh5::HDF5MeasFileWriterV5::SetChannelDataTypeInformation(const std::string& channel_name, const eCAL::eh5::DataTypeInformation& info) { - channels_[channel_name].Type = type; + auto type_descriptor = FromInfo(info); + channels_[channel_name].Type = type_descriptor.first; + channels_[channel_name].Description = type_descriptor.second; } long long eCAL::eh5::HDF5MeasFileWriterV5::GetMinTimestamp(const std::string& /*channel_name*/) const diff --git a/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.h b/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.h index 0b10238c41..579951cf70 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.h +++ b/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.h @@ -141,38 +141,23 @@ namespace eCAL bool HasChannel(const std::string& channel_name) const override; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - std::string GetChannelDescription(const std::string& channel_name) const override; - - /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel + * @brief Get data type information of the given channel + * + * @param channel_name channel name + * + * @return channel type **/ - void SetChannelDescription(const std::string& channel_name, const std::string& description) override; + DataTypeInformation GetChannelDataTypeInformation(const std::string & channel_name) const override; /** - * @brief Gets the channel type of the given channel - * - * @param channel_name channel name - * - * @return channel type - **/ - std::string GetChannelType(const std::string& channel_name) const override; - - /** - * @brief Set type of the given channel - * - * @param channel_name channel name - * @param type type of the channel + * @brief Set data type information of the given channel + * + * @param channel_name channel name + * @param info datatype info of the channel + * + * @return channel type **/ - void SetChannelType(const std::string& channel_name, const std::string& type) override; + void SetChannelDataTypeInformation(const std::string & channel_name, const DataTypeInformation & info) override; /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/ecalhdf5/src/eh5_meas_impl.h b/contrib/ecalhdf5/src/eh5_meas_impl.h index e1825b5103..cee99fac60 100644 --- a/contrib/ecalhdf5/src/eh5_meas_impl.h +++ b/contrib/ecalhdf5/src/eh5_meas_impl.h @@ -29,6 +29,39 @@ #include "ecalhdf5/eh5_types.h" +inline eCAL::eh5::DataTypeInformation CreateInfo(const std::string& combined_topic_type_, const std::string& descriptor_) +{ + eCAL::eh5::DataTypeInformation info; + auto pos = combined_topic_type_.find(':'); + if (pos == std::string::npos) + { + info.name = combined_topic_type_; + info.encoding = ""; + } + else + { + info.name = combined_topic_type_.substr(pos + 1); + info.encoding = combined_topic_type_.substr(0, pos); + } + info.descriptor = descriptor_; + return info; +} + +inline std::pair FromInfo(const eCAL::eh5::DataTypeInformation& datatype_info_) +{ + std::string combined_topic_type; + if (datatype_info_.encoding.empty()) + { + combined_topic_type = datatype_info_.name; + } + else + { + combined_topic_type = datatype_info_.encoding + ":" + datatype_info_.name; + } + + return std::make_pair(combined_topic_type, datatype_info_.descriptor); +} + namespace eCAL { namespace eh5 @@ -126,38 +159,23 @@ namespace eCAL virtual bool HasChannel(const std::string& channel_name) const = 0; /** - * @brief Get the channel description for the given channel - * - * @param channel_name channel name - * - * @return channel description - **/ - virtual std::string GetChannelDescription(const std::string& channel_name) const = 0; - - /** - * @brief Set description of the given channel - * - * @param channel_name channel name - * @param description description of the channel + * @brief Get data type information of the given channel + * + * @param channel_name channel name + * + * @return channel type **/ - virtual void SetChannelDescription(const std::string& channel_name, const std::string& description) = 0; + virtual DataTypeInformation GetChannelDataTypeInformation(const std::string& channel_name) const = 0; /** - * @brief Gets the channel type of the given channel - * - * @param channel_name channel name - * - * @return channel type - **/ - virtual std::string GetChannelType(const std::string& channel_name) const = 0; - - /** - * @brief Set type of the given channel - * - * @param channel_name channel name - * @param type type of the channel + * @brief Set data type information of the given channel + * + * @param channel_name channel name + * @param info datatype info of the channel + * + * @return channel type **/ - virtual void SetChannelType(const std::string& channel_name, const std::string& type) = 0; + virtual void SetChannelDataTypeInformation(const std::string& channel_name, const DataTypeInformation& info) = 0; /** * @brief Gets minimum timestamp for specified channel diff --git a/contrib/measurement/hdf5/src/reader.cpp b/contrib/measurement/hdf5/src/reader.cpp index 67481e41a9..2f9f3fd18b 100644 --- a/contrib/measurement/hdf5/src/reader.cpp +++ b/contrib/measurement/hdf5/src/reader.cpp @@ -5,27 +5,6 @@ using namespace eCAL::experimental::measurement::hdf5; using namespace eCAL::experimental::measurement; -namespace -{ - // To be removed soon-ish! - std::pair SplitCombinedTopicType(const std::string& combined_topic_type_) - { - auto pos = combined_topic_type_.find(':'); - if (pos == std::string::npos) - { - std::string encoding; - std::string type{ combined_topic_type_ }; - return std::make_pair(encoding, type); - } - else - { - std::string encoding = combined_topic_type_.substr(0, pos); - std::string type = combined_topic_type_.substr(pos + 1); - return std::make_pair(encoding, type); - } - } -} - Reader::Reader() : measurement(std::make_unique()) {} @@ -72,13 +51,7 @@ bool Reader::HasChannel(const std::string& channel_name) const base::DataTypeInformation Reader::GetChannelDataTypeInformation(const std::string& channel_name) const { - base::DataTypeInformation info; - auto type = measurement->GetChannelType(channel_name); - auto split_types = SplitCombinedTopicType(type); - info.encoding = split_types.first; - info.name = split_types.second; - info.descriptor = measurement->GetChannelDescription(channel_name); - return info; + return measurement->GetChannelDataTypeInformation(channel_name); } long long Reader::GetMinTimestamp(const std::string& channel_name) const diff --git a/contrib/measurement/hdf5/src/writer.cpp b/contrib/measurement/hdf5/src/writer.cpp index d28eb0666d..34fd56717e 100644 --- a/contrib/measurement/hdf5/src/writer.cpp +++ b/contrib/measurement/hdf5/src/writer.cpp @@ -4,21 +4,6 @@ using namespace eCAL::experimental::measurement::hdf5; using namespace eCAL::experimental::measurement; -namespace { - //To be removed soon - ish - std::string CombinedTopicEncodingAndType(const std::string & topic_encoding_, const std::string & topic_type_) - { - if (topic_encoding_.empty()) - { - return topic_type_; - } - else - { - return topic_encoding_ + ":" + topic_type_; - } - } -} - Writer::Writer() : measurement(std::make_unique()) {} @@ -70,9 +55,7 @@ void Writer::SetOneFilePerChannelEnabled(bool enabled) void Writer::SetChannelDataTypeInformation(const std::string& channel_name, const base::DataTypeInformation& info) { - - measurement->SetChannelType(channel_name, CombinedTopicEncodingAndType(info.encoding, info.name)); - measurement->SetChannelDescription(channel_name, info.descriptor); + measurement->SetChannelDataTypeInformation(channel_name, info); } void Writer::SetFileBaseName(const std::string& base_name) diff --git a/testing/contrib/ecalhdf5/hdf5_test/src/hdf5_test.cpp b/testing/contrib/ecalhdf5/hdf5_test/src/hdf5_test.cpp index bba0185736..2c5a5a2fd9 100644 --- a/testing/contrib/ecalhdf5/hdf5_test/src/hdf5_test.cpp +++ b/testing/contrib/ecalhdf5/hdf5_test/src/hdf5_test.cpp @@ -30,6 +30,23 @@ using namespace eCAL::experimental::measurement::base; +namespace eCAL +{ + namespace experimental + { + namespace measurement + { + namespace base + { + void PrintTo(const DataTypeInformation& info, std::ostream* os) { + *os << "(" << info.name << "," << info.encoding << "," << info.descriptor << ")"; + } + } + } + } +} + + namespace { struct TestingMeasEntry @@ -257,7 +274,6 @@ TEST(HDF5, ReadWrite) } - TEST(HDF5, IsOneFilePerChannelEnabled) { eCAL::eh5::HDF5Meas hdf5_writer; @@ -401,4 +417,85 @@ TEST(HDF5, EscapeFilenamesForOneFilePerChannel) ValidateDataInMeasurement(hdf5_reader, escape_ascii); ValidateDataInMeasurement(hdf5_reader, escape_ascii_2); } +} + +// This test validates that Datatypinformation is stored to / can be retrieved from the measurement correctly. +TEST(HDF5, WriteReadTopicTypeInformation) +{ + // Define data that will be written to the file + TestingMeasEntry entry; + DataTypeInformation info{ "mytype", "myencoding", "mydescriptor" }; + + std::string base_name = "datatypeinformation_meas"; + std::string meas_root_dir = output_dir + "/" + base_name; + + // Write HDF5 file + { + eCAL::eh5::HDF5Meas hdf5_writer; + + if (hdf5_writer.Open(meas_root_dir, eCAL::eh5::eAccessType::CREATE)) + { + hdf5_writer.SetFileBaseName(base_name); + hdf5_writer.SetMaxSizePerFile(max_size_per_file); + } + else + { + FAIL() << "Failed to open HDF5 Writer"; + } + + hdf5_writer.SetChannelDataTypeInformation(entry.channel_name, info); + EXPECT_TRUE(WriteToHDF(hdf5_writer, entry)); + + EXPECT_TRUE(hdf5_writer.Close()); + } + + // Read entries with HDF5 dir API + { + eCAL::eh5::HDF5Meas hdf5_reader; + EXPECT_TRUE(hdf5_reader.Open(meas_root_dir)); + EXPECT_EQ(hdf5_reader.GetChannelDataTypeInformation(entry.channel_name), info); + } +} + +TEST(HDF5, WriteReadTopicTypeInformationDeprecated) +{ + // Define data that will be written to the file + TestingMeasEntry entry; + std::string type = "myencoding:mytype"; + std::string descriptor = "mydescriptor"; + DataTypeInformation info{ "mytype", "myencoding", "mydescriptor" }; + + std::string base_name = "datatypeinformation_meas_deprecated"; + std::string meas_root_dir = output_dir + "/" + base_name; + + // Write HDF5 file + { + eCAL::eh5::HDF5Meas hdf5_writer; + + if (hdf5_writer.Open(meas_root_dir, eCAL::eh5::eAccessType::CREATE)) + { + hdf5_writer.SetFileBaseName(base_name); + hdf5_writer.SetMaxSizePerFile(max_size_per_file); + } + else + { + FAIL() << "Failed to open HDF5 Writer"; + } + + hdf5_writer.SetChannelType(entry.channel_name, type); + hdf5_writer.SetChannelDescription(entry.channel_name, descriptor); + + EXPECT_TRUE(WriteToHDF(hdf5_writer, entry)); + + EXPECT_TRUE(hdf5_writer.Close()); + } + + // Read entries with HDF5 dir API + { + eCAL::eh5::HDF5Meas hdf5_reader; + EXPECT_TRUE(hdf5_reader.Open(meas_root_dir)); + EXPECT_EQ(hdf5_reader.GetChannelType(entry.channel_name), type); + EXPECT_EQ(hdf5_reader.GetChannelDescription(entry.channel_name), descriptor); + EXPECT_EQ(hdf5_reader.GetChannelDataTypeInformation(entry.channel_name), info); + } } \ No newline at end of file From 13782a3db37a5fa77ea8601e585729db54014f81 Mon Sep 17 00:00:00 2001 From: Rex Schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:16:18 +0100 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- app/meas_cutter/src/measurement_importer.cpp | 2 +- app/play/play_core/src/measurement_container.h | 2 +- app/rec/rec_client_core/include/rec_client_core/topic_info.h | 2 +- app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp | 2 +- contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp | 2 +- .../measurement/base/include/ecal/measurement/omeasurement.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/meas_cutter/src/measurement_importer.cpp b/app/meas_cutter/src/measurement_importer.cpp index b38a8194a7..8394ddb582 100644 --- a/app/meas_cutter/src/measurement_importer.cpp +++ b/app/meas_cutter/src/measurement_importer.cpp @@ -179,7 +179,7 @@ bool MeasurementImporter::isEcalMeasFile(const std::string& path) bool MeasurementImporter::isProtoChannel(const eCAL::experimental::measurement::base::DataTypeInformation& channel_info) { - return (channel_info.encoding.compare("proto") == 0); + return (channel_info.encoding == "proto"); } std::string MeasurementImporter::getLoadedPath() diff --git a/app/play/play_core/src/measurement_container.h b/app/play/play_core/src/measurement_container.h index 66f47fa5a2..fa5cd691ff 100644 --- a/app/play/play_core/src/measurement_container.h +++ b/app/play/play_core/src/measurement_container.h @@ -92,7 +92,7 @@ class MeasurementContainer eCAL::CPublisher publisher_; long long message_counter_; - PublisherInfo(const std::string& topic_name, eCAL::SDataTypeInformation info_) + PublisherInfo(const std::string& topic_name, const eCAL::SDataTypeInformation& info_) : publisher_(topic_name, info_) , message_counter_(0) {} diff --git a/app/rec/rec_client_core/include/rec_client_core/topic_info.h b/app/rec/rec_client_core/include/rec_client_core/topic_info.h index ad50ac15e6..ee9e53a0f1 100644 --- a/app/rec/rec_client_core/include/rec_client_core/topic_info.h +++ b/app/rec/rec_client_core/include/rec_client_core/topic_info.h @@ -44,7 +44,7 @@ namespace eCAL eCAL::SDataTypeInformation tinfo_; // This should be removed once internally SDatatypeInformation is saved alongside with the publisher ID.. - std::string GetLegacyType() + std::string GetLegacyType() const { if (tinfo_.encoding.empty()) { diff --git a/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp b/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp index 1d446513f6..a84d47e3f5 100644 --- a/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp +++ b/app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp @@ -169,7 +169,7 @@ namespace eCAL for (const auto& topic : topic_info_map_to_set) { - eCAL::experimental::measurement::base::DataTypeInformation topic_info{ topic.second.tinfo_.name, topic.second.tinfo_.encoding, topic.second.tinfo_.descriptor }; + eCAL::experimental::measurement::base::DataTypeInformation const topic_info{ topic.second.tinfo_.name, topic.second.tinfo_.encoding, topic.second.tinfo_.descriptor }; hdf5_writer_->SetChannelDataTypeInformation(topic.first, topic_info); } } diff --git a/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp b/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp index f1aa1584cf..31d9f3916a 100644 --- a/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp +++ b/contrib/ecalhdf5/src/eh5_meas_file_writer_v5.cpp @@ -139,7 +139,7 @@ bool eCAL::eh5::HDF5MeasFileWriterV5::HasChannel(const std::string& /*channel_na } -eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5MeasFileWriterV5::GetChannelDataTypeInformation(const std::string& channel_name) const +eCAL::eh5::DataTypeInformation eCAL::eh5::HDF5MeasFileWriterV5::GetChannelDataTypeInformation(const std::string& /*channel_name*/) const { // UNSUPPORTED FUNCTION return eCAL::eh5::DataTypeInformation{}; diff --git a/contrib/measurement/base/include/ecal/measurement/omeasurement.h b/contrib/measurement/base/include/ecal/measurement/omeasurement.h index ca835d9474..9a4cb05356 100644 --- a/contrib/measurement/base/include/ecal/measurement/omeasurement.h +++ b/contrib/measurement/base/include/ecal/measurement/omeasurement.h @@ -132,7 +132,7 @@ namespace eCAL inline OChannel OMeasurement::Create(const std::string& channel) const { static T msg; - eCAL::experimental::measurement::base::DataTypeInformation datatype_info; + eCAL::experimental::measurement::base::DataTypeInformation const datatype_info; datatype_info.name = eCAL::message::GetTypeName(msg); datatype_info.encoding = eCAL::message::GetEncoding(msg); datatype_info.descriptor = eCAL::message::GetDescription(msg); From f3a25311ec1adeddb425c2551fb8261bbdc84d7b Mon Sep 17 00:00:00 2001 From: Kerstin Keller Date: Wed, 14 Feb 2024 10:26:55 +0100 Subject: [PATCH 4/4] Fix clang-tidy suggestion. --- .../base/include/ecal/measurement/omeasurement.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contrib/measurement/base/include/ecal/measurement/omeasurement.h b/contrib/measurement/base/include/ecal/measurement/omeasurement.h index 9a4cb05356..09f92c3763 100644 --- a/contrib/measurement/base/include/ecal/measurement/omeasurement.h +++ b/contrib/measurement/base/include/ecal/measurement/omeasurement.h @@ -132,10 +132,11 @@ namespace eCAL inline OChannel OMeasurement::Create(const std::string& channel) const { static T msg; - eCAL::experimental::measurement::base::DataTypeInformation const datatype_info; - datatype_info.name = eCAL::message::GetTypeName(msg); - datatype_info.encoding = eCAL::message::GetEncoding(msg); - datatype_info.descriptor = eCAL::message::GetDescription(msg); + const eCAL::experimental::measurement::base::DataTypeInformation datatype_info{ + eCAL::message::GetTypeName(msg), + eCAL::message::GetEncoding(msg), + eCAL::message::GetDescription(msg) + }; meas->SetChannelDataTypeInformation(channel, datatype_info); // Construct a channel based return OChannel{meas, channel};