protocol: Fix message types in modules that don't specify _MsgOrder

This commit is contained in:
Joshua Scott 2018-04-06 03:07:35 +01:00
parent 6a84d50cee
commit 9ef780ace1
3 changed files with 44 additions and 7 deletions

View File

@ -3,7 +3,6 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
#include <array>
#include <map> #include <map>
namespace ki namespace ki
@ -31,6 +30,8 @@ namespace dml
const MessageTemplate *get_message_template(uint8_t type) const; const MessageTemplate *get_message_template(uint8_t type) const;
const MessageTemplate *get_message_template(std::string name) const; const MessageTemplate *get_message_template(std::string name) const;
void sort_lookup();
MessageBuilder &build_message(uint8_t message_type) const; MessageBuilder &build_message(uint8_t message_type) const;
MessageBuilder &build_message(std::string message_name) const; MessageBuilder &build_message(std::string message_name) const;
private: private:
@ -39,7 +40,8 @@ namespace dml
std::string m_protocol_description; std::string m_protocol_description;
uint8_t m_last_message_type; uint8_t m_last_message_type;
std::array<MessageTemplate *, 255> m_templates; std::vector<MessageTemplate *> m_templates;
std::map<uint8_t, MessageTemplate *> m_message_type_map;
std::map<std::string, MessageTemplate *> m_message_name_map; std::map<std::string, MessageTemplate *> m_message_name_map;
}; };

View File

@ -56,6 +56,8 @@ namespace dml
// It's safe to allocate the module we're working on now // It's safe to allocate the module we're working on now
auto *message_module = new MessageModule(); auto *message_module = new MessageModule();
bool sort_required = true;
bool first_message = true;
// Get the root node and iterate through children // Get the root node and iterate through children
// Each child is a MessageTemplate // Each child is a MessageTemplate
@ -88,6 +90,13 @@ namespace dml
} }
else else
{ {
// Base sorting on whether the first message has the _MsgOrder field.
if (first_message)
{
sort_required = !record->has_field("_MsgOrder");
first_message = false;
}
// The template will use the record itself to figure out name and type; // 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. // 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); auto *message_template = message_module->add_message_template(message_name, record);
@ -105,6 +114,10 @@ namespace dml
} }
} }
// Sort the module's lookup if we need to
if (sort_required)
message_module->sort_lookup();
// Make sure we aren't overwriting another module // Make sure we aren't overwriting another module
if (m_service_id_map.count(message_module->get_service_id()) == 1) if (m_service_id_map.count(message_module->get_service_id()) == 1)
{ {

View File

@ -14,7 +14,6 @@ namespace dml
m_protocol_type = protocol_type; m_protocol_type = protocol_type;
m_protocol_description = ""; m_protocol_description = "";
m_last_message_type = 0; m_last_message_type = 0;
m_templates = std::array<MessageTemplate *, 255> { nullptr };
} }
MessageModule::~MessageModule() MessageModule::~MessageModule()
@ -67,7 +66,7 @@ namespace dml
// Do we already have a message template with this name? // Do we already have a message template with this name?
if (m_message_name_map.count(name) == 1) if (m_message_name_map.count(name) == 1)
return nullptr; return m_message_name_map.at(name);
// Message type is based on the _MsgOrder field if it's present // Message type is based on the _MsgOrder field if it's present
// Otherwise it just goes in order of added templates // Otherwise it just goes in order of added templates
@ -83,12 +82,13 @@ namespace dml
return nullptr; return nullptr;
// Do we already have a message template with this type? // Do we already have a message template with this type?
if (m_templates[message_type] != nullptr) if (m_message_type_map.count(message_type) == 1)
return nullptr; return nullptr;
// Create the template and add it to our maps // Create the template and add it to our maps
auto *message_template = new MessageTemplate(name, message_type, record); auto *message_template = new MessageTemplate(name, message_type, record);
m_templates[message_type] = message_template; m_templates.push_back(message_template);
m_message_type_map.insert({ message_type, message_template });
m_message_name_map.insert({ name, message_template }); m_message_name_map.insert({ name, message_template });
m_last_message_type = message_type; m_last_message_type = message_type;
return message_template; return message_template;
@ -96,7 +96,9 @@ namespace dml
const MessageTemplate *MessageModule::get_message_template(uint8_t type) const const MessageTemplate *MessageModule::get_message_template(uint8_t type) const
{ {
return m_templates[type]; if (m_message_type_map.count(type) == 1)
return m_message_type_map.at(type);
return nullptr;
} }
const MessageTemplate *MessageModule::get_message_template(std::string name) const const MessageTemplate *MessageModule::get_message_template(std::string name) const
@ -106,6 +108,26 @@ namespace dml
return nullptr; return nullptr;
} }
void MessageModule::sort_lookup()
{
uint8_t message_type = 1;
// First, clear the message type map since we're going to be
// moving everything around
m_message_type_map.clear();
// Iterating over a map with std::string as the key
// is guaranteed to be in alphabetical order
for (auto it = m_message_name_map.begin();
it != m_message_name_map.end(); ++it)
{
auto *message_template = it->second;
message_template->set_type(message_type);
m_message_type_map.insert({ message_type, message_template });
message_type++;
}
}
MessageBuilder& MessageModule::build_message(uint8_t message_type) const MessageBuilder& MessageModule::build_message(uint8_t message_type) const
{ {
auto *message_template = get_message_template(message_type); auto *message_template = get_message_template(message_type);