mirror of https://github.com/SeanOMik/libki.git
protocol: Implement module loading and I/O for DML messages
'das alota cod
This commit is contained in:
parent
c618e7d536
commit
3e34c0b3bc
|
@ -13,7 +13,7 @@ namespace dml
|
|||
{
|
||||
public:
|
||||
Message(uint8_t service_id = 0, uint8_t type = 0);
|
||||
virtual ~Message() = default;
|
||||
virtual ~Message();
|
||||
|
||||
uint8_t get_service_id() const;
|
||||
void set_service_id(uint8_t service_id);
|
||||
|
@ -21,16 +21,35 @@ namespace dml
|
|||
uint8_t get_type() const;
|
||||
void set_type(uint8_t type);
|
||||
|
||||
ki::dml::Record &get_record();
|
||||
const ki::dml::Record &get_record() const;
|
||||
ki::dml::Record *get_record();
|
||||
const ki::dml::Record *get_record() const;
|
||||
|
||||
/**
|
||||
* Sets the record to a copy of the specified record.
|
||||
*/
|
||||
void set_record(const ki::dml::Record &record);
|
||||
|
||||
/**
|
||||
* If raw data is present, then this uses the specified record
|
||||
* to parse the raw DML message payload into a new Record.
|
||||
* If raw data is not present, this is equivalent to set_record.
|
||||
*
|
||||
* If the raw data is parsed successfully, the internal raw
|
||||
* data is cleared, and calls to get_record will return a valid
|
||||
* Record pointer.
|
||||
*
|
||||
* However, if the raw data is not parsed successfully, then
|
||||
* calls to get_record will still return nullptr.
|
||||
*/
|
||||
void use_template_record(const ki::dml::Record &record);
|
||||
|
||||
void write_to(std::ostream &ostream) const override final;
|
||||
void read_from(std::istream &istream) override final;
|
||||
size_t get_size() const override final;
|
||||
private:
|
||||
uint8_t m_service_id;
|
||||
uint8_t m_type;
|
||||
std::vector<char> m_raw_data;
|
||||
ki::dml::Record *m_record;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,24 +13,28 @@ namespace dml
|
|||
class MessageManager
|
||||
{
|
||||
public:
|
||||
MessageManager();
|
||||
MessageManager() = default;
|
||||
~MessageManager();
|
||||
|
||||
static MessageManager &get_singleton();
|
||||
|
||||
const MessageModule &load_module(std::string filepath);
|
||||
const MessageModule &get_module(uint8_t service_id) const;
|
||||
const MessageModule &get_module(std::string protocol_type) const;
|
||||
const MessageModule *load_module(std::string filepath);
|
||||
const MessageModule *get_module(uint8_t service_id) const;
|
||||
const MessageModule *get_module(const std::string &protocol_type) const;
|
||||
|
||||
MessageBuilder &build_message(uint8_t service_id, uint8_t message_type) const;
|
||||
MessageBuilder &build_message(uint8_t service_id, std::string message_name) const;
|
||||
MessageBuilder &build_message(std::string service_type, uint8_t message_type) const;
|
||||
MessageBuilder &build_message(std::string service_type, std::string message_name) const;
|
||||
MessageBuilder &build_message(uint8_t service_id, const std::string &message_name) const;
|
||||
MessageBuilder &build_message(const std::string &protocol_type, uint8_t message_type) const;
|
||||
MessageBuilder &build_message(const std::string &protocol_type, const std::string &message_name) const;
|
||||
|
||||
const Message *from_binary(std::istream &istream);
|
||||
/**
|
||||
* If the DML message header cannot be read, then a nullptr
|
||||
* is returned; otherwise, a valid Message pointer is always returned.
|
||||
* However, that does not mean that the message itself is valid.
|
||||
*
|
||||
* To verify if the record was completely parsed, get_record
|
||||
* should return a valid Record pointer, rather than nullptr.
|
||||
*/
|
||||
const Message *message_from_binary(std::istream &istream) const;
|
||||
private:
|
||||
static MessageManager *g_instance;
|
||||
|
||||
MessageModuleList m_modules;
|
||||
MessageModuleServiceIdMap m_service_id_map;
|
||||
MessageModuleProtocolTypeMap m_protocol_type_map;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
namespace ki
|
||||
|
@ -14,7 +15,7 @@ namespace dml
|
|||
class MessageModule
|
||||
{
|
||||
public:
|
||||
MessageModule(uint8_t service_id, std::string protocol_type);
|
||||
MessageModule(uint8_t service_id = 0, std::string protocol_type = "");
|
||||
~MessageModule();
|
||||
|
||||
uint8_t get_service_id() const;
|
||||
|
@ -26,10 +27,9 @@ namespace dml
|
|||
std::string get_protocol_desription() const;
|
||||
void set_protocol_description(std::string protocol_description);
|
||||
|
||||
const MessageTemplate &add_message_template(std::string name, uint8_t type,
|
||||
ki::dml::Record *record);
|
||||
const MessageTemplate &get_message_template(uint8_t type);
|
||||
const MessageTemplate &get_message_template(std::string name);
|
||||
const MessageTemplate *add_message_template(std::string name, ki::dml::Record *record);
|
||||
const MessageTemplate *get_message_template(uint8_t type) const;
|
||||
const MessageTemplate *get_message_template(std::string name) const;
|
||||
|
||||
MessageBuilder &build_message(uint8_t message_type) const;
|
||||
MessageBuilder &build_message(std::string message_name) const;
|
||||
|
@ -37,10 +37,10 @@ namespace dml
|
|||
uint8_t m_service_id;
|
||||
std::string m_protocol_type;
|
||||
std::string m_protocol_description;
|
||||
uint8_t m_last_message_type;
|
||||
|
||||
std::vector<MessageTemplate *> m_templates;
|
||||
std::array<MessageTemplate *, 255> m_templates;
|
||||
std::map<std::string, MessageTemplate *> m_message_name_map;
|
||||
std::map<uint8_t, MessageTemplate *> m_message_type_map;
|
||||
};
|
||||
|
||||
typedef std::vector<MessageModule *> MessageModuleList;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace dml
|
|||
const ki::dml::Record &get_record() const;
|
||||
void set_record(ki::dml::Record *record);
|
||||
|
||||
MessageBuilder &build_message();
|
||||
MessageBuilder &build_message() const;
|
||||
private:
|
||||
std::string m_name;
|
||||
uint8_t m_type;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
#include <stdexcept>
|
||||
|
||||
namespace ki
|
||||
{
|
||||
namespace protocol
|
||||
{
|
||||
class runtime_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
runtime_error(std::string message) : std::runtime_error(message) { }
|
||||
};
|
||||
|
||||
class parse_error : public runtime_error
|
||||
{
|
||||
public:
|
||||
parse_error(std::string message) : runtime_error(message) { }
|
||||
};
|
||||
|
||||
class value_error : public runtime_error
|
||||
{
|
||||
public:
|
||||
value_error(std::string message) : runtime_error(message) { }
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#include "ki/protocol/dml/Message.h"
|
||||
#include "ki/protocol/exception.h"
|
||||
|
||||
namespace ki
|
||||
{
|
||||
|
@ -6,7 +7,125 @@ namespace protocol
|
|||
{
|
||||
namespace dml
|
||||
{
|
||||
Message::Message(uint8_t service_id, uint8_t type)
|
||||
{
|
||||
m_service_id = service_id;
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
delete m_record;
|
||||
}
|
||||
|
||||
uint8_t Message::get_service_id() const
|
||||
{
|
||||
return m_service_id;
|
||||
}
|
||||
|
||||
void Message::set_service_id(uint8_t service_id)
|
||||
{
|
||||
m_service_id = service_id;
|
||||
}
|
||||
|
||||
uint8_t Message::get_type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void Message::set_type(uint8_t type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
ki::dml::Record *Message::get_record()
|
||||
{
|
||||
return m_record;
|
||||
}
|
||||
|
||||
const ki::dml::Record *Message::get_record() const
|
||||
{
|
||||
return m_record;
|
||||
}
|
||||
|
||||
void Message::set_record(const ki::dml::Record &record)
|
||||
{
|
||||
m_record = new ki::dml::Record(record);
|
||||
}
|
||||
|
||||
void Message::use_template_record(const ki::dml::Record &record)
|
||||
{
|
||||
set_record(record);
|
||||
if (!m_raw_data.empty())
|
||||
{
|
||||
std::istringstream iss(std::string(m_raw_data.data(), m_raw_data.size()));
|
||||
try
|
||||
{
|
||||
m_record->read_from(iss);
|
||||
m_raw_data.clear();
|
||||
}
|
||||
catch (ki::dml::parse_error &e)
|
||||
{
|
||||
delete m_record;
|
||||
m_record = nullptr;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Error reading DML message payload: " << e.what();
|
||||
throw parse_error(oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Message::write_to(std::ostream &ostream) const
|
||||
{
|
||||
ki::dml::Record record;
|
||||
record.add_field<ki::dml::UBYT>("m_service_id")->set_value(m_service_id);
|
||||
record.add_field<ki::dml::UBYT>("m_type")->set_value(m_type);
|
||||
auto *size_field = record.add_field<ki::dml::USHRT>("size");
|
||||
if (m_record)
|
||||
size_field->set_value(m_record->get_size() + 4);
|
||||
else
|
||||
size_field->set_value(m_raw_data.size() + 4);
|
||||
record.write_to(ostream);
|
||||
|
||||
if (m_record)
|
||||
record.write_to(ostream);
|
||||
else
|
||||
ostream.write(m_raw_data.data(), m_raw_data.size());
|
||||
}
|
||||
|
||||
void Message::read_from(std::istream &istream)
|
||||
{
|
||||
ki::dml::Record record;
|
||||
auto *service_id_field = record.add_field<ki::dml::UBYT>("ServiceID");
|
||||
auto *message_type_field = record.add_field<ki::dml::UBYT>("MsgType");
|
||||
auto *size_field = record.add_field<ki::dml::USHRT>("Length");
|
||||
try
|
||||
{
|
||||
record.read_from(istream);
|
||||
}
|
||||
catch (ki::dml::parse_error &e)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Error reading DML message header: " << e.what();
|
||||
throw parse_error(oss.str());
|
||||
}
|
||||
|
||||
m_service_id = service_id_field->get_value();
|
||||
m_type = message_type_field->get_value();
|
||||
const ki::dml::USHRT size = size_field->get_value() - 4;
|
||||
m_raw_data.resize(size);
|
||||
istream.read(m_raw_data.data(), size);
|
||||
if (istream.fail())
|
||||
throw parse_error("Not enough data was available to read DML message payload.");
|
||||
}
|
||||
|
||||
size_t Message::get_size() const
|
||||
{
|
||||
if (m_record)
|
||||
return 4 + m_record->get_size();
|
||||
return 4 + m_raw_data.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,10 @@
|
|||
#include "ki/protocol/dml/MessageManager.h"
|
||||
#include "ki/protocol/exception.h"
|
||||
#include "ki/dml/Record.h"
|
||||
#include "ki/util/ValueBytes.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <rapidxml.hpp>
|
||||
|
||||
namespace ki
|
||||
{
|
||||
|
@ -6,7 +12,225 @@ namespace protocol
|
|||
{
|
||||
namespace dml
|
||||
{
|
||||
MessageManager::~MessageManager()
|
||||
{
|
||||
for (auto it = m_modules.begin();
|
||||
it != m_modules.end(); ++it)
|
||||
delete *it;
|
||||
m_modules.clear();
|
||||
m_service_id_map.clear();
|
||||
m_protocol_type_map.clear();
|
||||
}
|
||||
|
||||
const MessageModule *MessageManager::load_module(std::string filepath)
|
||||
{
|
||||
// Open the file
|
||||
std::ifstream ifs(filepath, std::ios::ate);
|
||||
if (!ifs.is_open())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Could not open file: " << filepath;
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
// Load contents into memory
|
||||
size_t size = ifs.tellg();
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
char *data = new char[size + 1] { 0 };
|
||||
ifs.read(data, size);
|
||||
|
||||
// Parse the contents
|
||||
rapidxml::xml_document<> doc;
|
||||
try
|
||||
{
|
||||
doc.parse<0>(data);
|
||||
}
|
||||
catch (rapidxml::parse_error &e)
|
||||
{
|
||||
delete[] data;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Failed to parse: " << filepath;
|
||||
throw parse_error(oss.str());
|
||||
}
|
||||
|
||||
// It's safe to allocate the module we're working on now
|
||||
auto *message_module = new MessageModule();
|
||||
|
||||
// Get the root node and iterate through children
|
||||
// Each child is a MessageTemplate
|
||||
auto *root = doc.first_node();
|
||||
for (auto *node = root->first_node();
|
||||
node; node = node->next_sibling())
|
||||
{
|
||||
// Parse the record node inside this node
|
||||
auto *record_node = node->first_node();
|
||||
if (!record_node)
|
||||
continue;
|
||||
auto *record = new ki::dml::Record();
|
||||
record->from_xml(record_node);
|
||||
|
||||
// The message name is initially based on the element name
|
||||
const std::string message_name = node->name();
|
||||
if (message_name == "_ProtocolInfo")
|
||||
{
|
||||
auto *service_id_field = record->get_field<ki::dml::UBYT>("ServiceID");
|
||||
auto *type_field = record->get_field<ki::dml::STR>("ProtocolType");
|
||||
auto *description_field = record->get_field<ki::dml::STR>("ProtocolDescription");
|
||||
|
||||
// Set the module metadata from this template
|
||||
if (service_id_field)
|
||||
message_module->set_service_id(service_id_field->get_value());
|
||||
if (type_field)
|
||||
message_module->set_protocol_type(type_field->get_value());
|
||||
if (description_field)
|
||||
message_module->set_protocol_description(description_field->get_value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The template will use the record itself to figure out name and type;
|
||||
// we only give the XML data incase the record doesn't have it defined.
|
||||
auto *message_template = message_module->add_message_template(message_name, record);
|
||||
if (!message_template)
|
||||
{
|
||||
delete[] data;
|
||||
delete message_module;
|
||||
delete record;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Failed to create message template for ";
|
||||
oss << message_name;
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we aren't overwriting another module
|
||||
if (m_service_id_map.count(message_module->get_service_id()) == 1)
|
||||
{
|
||||
delete[] data;
|
||||
delete message_module;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Message Module has already been loaded with Service ID ";
|
||||
oss << message_module->get_service_id();
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
if (m_protocol_type_map.count(message_module->get_protocol_type()) == 1)
|
||||
{
|
||||
delete[] data;
|
||||
delete message_module;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Message Module has already been loaded with Protocol Type ";
|
||||
oss << message_module->get_protocol_type();
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
// Add it to our maps
|
||||
m_modules.push_back(message_module);
|
||||
m_service_id_map.insert({ message_module->get_service_id(), message_module });
|
||||
m_protocol_type_map.insert({ message_module->get_protocol_type(), message_module });
|
||||
|
||||
delete[] data;
|
||||
return message_module;
|
||||
}
|
||||
|
||||
const MessageModule *MessageManager::get_module(uint8_t service_id) const
|
||||
{
|
||||
if (m_service_id_map.count(service_id) == 1)
|
||||
return m_service_id_map.at(service_id);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MessageModule *MessageManager::get_module(const std::string &protocol_type) const
|
||||
{
|
||||
if (m_protocol_type_map.count(protocol_type) == 1)
|
||||
return m_protocol_type_map.at(protocol_type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MessageBuilder &MessageManager::build_message(uint8_t service_id, uint8_t message_type) const
|
||||
{
|
||||
auto *message_module = get_module(service_id);
|
||||
if (!message_module)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No service exists with id: " << service_id;
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
return message_module->build_message(message_type);
|
||||
}
|
||||
|
||||
MessageBuilder& MessageManager::build_message(uint8_t service_id, const std::string& message_name) const
|
||||
{
|
||||
auto *message_module = get_module(service_id);
|
||||
if (!message_module)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No service exists with id: " << service_id;
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
return message_module->build_message(message_name);
|
||||
}
|
||||
|
||||
MessageBuilder& MessageManager::build_message(const std::string& protocol_type, uint8_t message_type) const
|
||||
{
|
||||
auto *message_module = get_module(protocol_type);
|
||||
if (!message_module)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No service exists with protocol type: " << protocol_type;
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
return message_module->build_message(message_type);
|
||||
}
|
||||
|
||||
MessageBuilder& MessageManager::build_message(const std::string& protocol_type, const std::string& message_name) const
|
||||
{
|
||||
auto *message_module = get_module(protocol_type);
|
||||
if (!message_module)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No service exists with protocol type: " << protocol_type;
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
return message_module->build_message(message_name);
|
||||
}
|
||||
|
||||
const Message *MessageManager::message_from_binary(std::istream& istream) const
|
||||
{
|
||||
// Read the message header and raw payload
|
||||
Message *message = new Message();
|
||||
try
|
||||
{
|
||||
message->read_from(istream);
|
||||
}
|
||||
catch (parse_error &e)
|
||||
{
|
||||
delete message;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the message module that uses the specified service id
|
||||
auto *message_module = get_module(message->get_service_id());
|
||||
if (!message_module)
|
||||
return message;
|
||||
|
||||
// Get the message template for this message type
|
||||
auto *message_template = message_module->get_message_template(message->get_type());
|
||||
if (!message_template)
|
||||
return message;
|
||||
|
||||
// Parse the raw payload with the template
|
||||
message->use_template_record(message_template->get_record());
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
#include "ki/protocol/dml/MessageModule.h"
|
||||
#include "ki/protocol/exception.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace ki
|
||||
{
|
||||
|
@ -6,7 +8,133 @@ namespace protocol
|
|||
{
|
||||
namespace dml
|
||||
{
|
||||
MessageModule::MessageModule(uint8_t service_id, std::string protocol_type)
|
||||
{
|
||||
m_service_id = service_id;
|
||||
m_protocol_type = protocol_type;
|
||||
m_protocol_description = "";
|
||||
m_last_message_type = 0;
|
||||
m_templates = std::array<MessageTemplate *, 255> { nullptr };
|
||||
}
|
||||
|
||||
MessageModule::~MessageModule()
|
||||
{
|
||||
for (auto it = m_templates.begin();
|
||||
it != m_templates.end(); ++it)
|
||||
delete *it;
|
||||
m_message_name_map.clear();
|
||||
}
|
||||
|
||||
uint8_t MessageModule::get_service_id() const
|
||||
{
|
||||
return m_service_id;
|
||||
}
|
||||
|
||||
void MessageModule::set_service_id(uint8_t service_id)
|
||||
{
|
||||
m_service_id = service_id;
|
||||
}
|
||||
|
||||
std::string MessageModule::get_protocol_type() const
|
||||
{
|
||||
return m_protocol_type;
|
||||
}
|
||||
|
||||
void MessageModule::set_protocol_type(std::string protocol_type)
|
||||
{
|
||||
m_protocol_type = protocol_type;
|
||||
}
|
||||
|
||||
std::string MessageModule::get_protocol_desription() const
|
||||
{
|
||||
return m_protocol_description;
|
||||
}
|
||||
|
||||
void MessageModule::set_protocol_description(std::string protocol_description)
|
||||
{
|
||||
m_protocol_description = protocol_description;
|
||||
}
|
||||
|
||||
const MessageTemplate *MessageModule::add_message_template(std::string name, ki::dml::Record *record)
|
||||
{
|
||||
if (!record)
|
||||
return nullptr;
|
||||
|
||||
// If the field exists, get the name from the record rather than the XML
|
||||
auto *name_field = record->get_field<ki::dml::STR>("_MsgName");
|
||||
if (name_field)
|
||||
name = name_field->get_value();
|
||||
|
||||
// Do we already have a message template with this name?
|
||||
if (m_message_name_map.count(name) == 1)
|
||||
return nullptr;
|
||||
|
||||
// Message type is based on the _MsgOrder field if it's present
|
||||
// Otherwise it just goes in order of added templates
|
||||
uint8_t message_type;
|
||||
auto *order_field = record->get_field<ki::dml::UBYT>("_MsgOrder");
|
||||
if (order_field)
|
||||
message_type = order_field->get_value();
|
||||
else
|
||||
message_type = m_last_message_type + 1;
|
||||
|
||||
// Don't allow message type to be zero
|
||||
if (message_type == 0)
|
||||
return nullptr;
|
||||
|
||||
// Do we already have a message template with this type?
|
||||
if (m_templates[message_type] != nullptr)
|
||||
return nullptr;
|
||||
|
||||
// Create the template and add it to our maps
|
||||
auto *message_template = new MessageTemplate(name, message_type, record);
|
||||
m_templates[message_type] = message_template;
|
||||
m_message_name_map.insert({ name, message_template });
|
||||
m_last_message_type = message_type;
|
||||
return message_template;
|
||||
}
|
||||
|
||||
const MessageTemplate *MessageModule::get_message_template(uint8_t type) const
|
||||
{
|
||||
return m_templates[type];
|
||||
}
|
||||
|
||||
const MessageTemplate *MessageModule::get_message_template(std::string name) const
|
||||
{
|
||||
if (m_message_name_map.count(name) == 1)
|
||||
return m_message_name_map.at(name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MessageBuilder& MessageModule::build_message(uint8_t message_type) const
|
||||
{
|
||||
auto *message_template = get_message_template(message_type);
|
||||
if (!message_template)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No message exists with type: " << message_type;
|
||||
oss << "(service=" << m_protocol_type << ")";
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
return message_template->build_message()
|
||||
.set_service_id(m_service_id);
|
||||
}
|
||||
|
||||
MessageBuilder &MessageModule::build_message(std::string message_name) const
|
||||
{
|
||||
auto *message_template = get_message_template(message_name);
|
||||
if (!message_template)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No message exists with name: " << message_name;
|
||||
oss << "(service=" << m_protocol_type << ")";
|
||||
throw value_error(oss.str());
|
||||
}
|
||||
|
||||
return message_template->build_message()
|
||||
.set_service_id(m_service_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,54 @@ namespace protocol
|
|||
{
|
||||
namespace dml
|
||||
{
|
||||
MessageTemplate::MessageTemplate(std::string name, uint8_t type, ki::dml::Record* record)
|
||||
{
|
||||
m_name = name;
|
||||
m_type = type;
|
||||
m_record = record;
|
||||
}
|
||||
|
||||
MessageTemplate::~MessageTemplate()
|
||||
{
|
||||
delete m_record;
|
||||
}
|
||||
|
||||
std::string MessageTemplate::get_name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void MessageTemplate::set_name(std::string name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
uint8_t MessageTemplate::get_type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void MessageTemplate::set_type(uint8_t type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
const ki::dml::Record& MessageTemplate::get_record() const
|
||||
{
|
||||
return *m_record;
|
||||
}
|
||||
|
||||
void MessageTemplate::set_record(ki::dml::Record* record)
|
||||
{
|
||||
m_record = record;
|
||||
}
|
||||
|
||||
MessageBuilder &MessageTemplate::build_message() const
|
||||
{
|
||||
return MessageBuilder()
|
||||
.set_message_type(m_type)
|
||||
.use_template_record(*m_record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue