diff --git a/include/ki/dml/Field.h b/include/ki/dml/Field.h index 6facc9a..a175d42 100644 --- a/include/ki/dml/Field.h +++ b/include/ki/dml/Field.h @@ -36,6 +36,7 @@ namespace dml void write_to(std::ostream &ostream) const override final; void read_from(std::istream &istream) override final; + void read_from(std::istream& istream, size_t bit_count = sizeof(ValueT)); size_t get_size() const override final; /** @@ -121,6 +122,7 @@ namespace dml void set_value_from_string(std::string value) override final; private: ValueT m_value; + size_t m_bit_count = 0; /** * Returns a new Field with the same name, transferability, diff --git a/include/ki/dml/Record.h b/include/ki/dml/Record.h index c0b52b2..53f0056 100644 --- a/include/ki/dml/Record.h +++ b/include/ki/dml/Record.h @@ -97,11 +97,33 @@ namespace dml return field; } + template + Field* add_field(std::string name, size_t bit_count, bool transferable = true) { + // Does this field already exist? + if (has_field(name)) { + // Return nullptr if the type is not the same + auto* field = m_field_map.at(name); + if (!field->is_type()) + return nullptr; + return dynamic_cast*>(field); + } + + // Create the field + auto* field = new Field(name); + field->m_transferable = transferable; + field->m_bit_count = bit_count; + add_field(field); + return field; + } + size_t get_field_count() const; FieldList::const_iterator fields_begin() const; FieldList::const_iterator fields_end() const; + FieldList::iterator fields_begin(); + FieldList::iterator fields_end(); + void write_to(std::ostream &ostream) const override final; void read_from(std::istream &istream) override final; size_t get_size() const override final; diff --git a/include/ki/protocol/dml/Message.h b/include/ki/protocol/dml/Message.h index bddbb35..41682a1 100644 --- a/include/ki/protocol/dml/Message.h +++ b/include/ki/protocol/dml/Message.h @@ -36,6 +36,19 @@ namespace dml void write_to(std::ostream &ostream) const override final; void read_from(std::istream &istream) override final; size_t get_size() const override final; + + void set_raw_data(const std::vector& data); + const std::vector get_raw_data() const { + return m_raw_data; + } + + void set_header(MessageHeader header) { + m_header = header; + } + + void set_record(ki::dml::Record* record) { + m_record = record; + } private: const MessageTemplate *m_template; ki::dml::Record *m_record; @@ -47,4 +60,4 @@ namespace dml }; } } -} +} \ No newline at end of file diff --git a/include/ki/protocol/dml/MessageTemplate.h b/include/ki/protocol/dml/MessageTemplate.h index fc51220..b0613a1 100644 --- a/include/ki/protocol/dml/MessageTemplate.h +++ b/include/ki/protocol/dml/MessageTemplate.h @@ -36,7 +36,7 @@ namespace dml void set_record(ki::dml::Record *record); Message *create_message() const; - private: + protected: std::string m_name; uint8_t m_type; uint8_t m_service_id; diff --git a/src/dml/Record.cpp b/src/dml/Record.cpp index 7fa7d5d..68f1e74 100644 --- a/src/dml/Record.cpp +++ b/src/dml/Record.cpp @@ -59,6 +59,14 @@ namespace dml return m_fields.end(); } + FieldList::iterator Record::fields_begin() { + return m_fields.begin(); + } + + FieldList::iterator Record::fields_end() { + return m_fields.end(); + } + void Record::write_to(std::ostream &ostream) const { for (auto it = m_fields.begin(); it != m_fields.end(); ++it) diff --git a/src/dml/types/BytField.cpp b/src/dml/types/BytField.cpp index 7b0a0f4..11a274b 100644 --- a/src/dml/types/BytField.cpp +++ b/src/dml/types/BytField.cpp @@ -16,8 +16,10 @@ namespace dml template <> void BytField::read_from(std::istream &istream) { + size_t bit_count = (m_bit_count != 0) ? m_bit_count : sizeof(BYT); + ValueBytes data; - istream.read(data.buff, sizeof(BYT)); + istream.read(data.buff, bit_count); if (istream.fail()) { std::ostringstream oss; diff --git a/src/protocol/dml/Message.cpp b/src/protocol/dml/Message.cpp index a2a3d38..9114eca 100644 --- a/src/protocol/dml/Message.cpp +++ b/src/protocol/dml/Message.cpp @@ -1,3 +1,4 @@ +#include "..\..\..\include\ki\protocol\dml\Message.h" #include "ki/protocol/dml/Message.h" #include "ki/protocol/dml/MessageTemplate.h" #include "ki/protocol/exception.h" @@ -135,7 +136,11 @@ namespace dml void Message::read_from(std::istream &istream) { - m_header.read_from(istream); + // Check if we need to read for the header + if (m_header.get_size() == 0) { + m_header.read_from(istream); + } + if (m_template) { // Check for mismatches between the header and template @@ -167,6 +172,10 @@ namespace dml if (m_record) return m_header.get_size() + m_record->get_size(); return 4 + m_raw_data.size(); + } + + void Message::set_raw_data(const std::vector& data) { + m_raw_data = data; } } } diff --git a/src/protocol/dml/MessageManager.cpp b/src/protocol/dml/MessageManager.cpp index 70c43c5..807062b 100644 --- a/src/protocol/dml/MessageManager.cpp +++ b/src/protocol/dml/MessageManager.cpp @@ -250,9 +250,10 @@ namespace dml // Create a new Message from the template auto *message = new Message(message_template); + message->set_header(header); try { - message->get_record()->read_from(istream); + message->read_from(istream); } catch (ki::dml::parse_error &e) {