Структура данных для представления формата командного пакета - PullRequest
1 голос
/ 12 мая 2019

Моя цель - создать файл конфигурации.Поэтому я в основном должен представлять структуры командных пакетов каким-то образом.

Когда поступают фактические данные (двоичные), я хочу сравнить пакет с этим файлом конфигурации и затем обработать его (преобразовать данные в формат CSV).

Так что есть разные типы команд.

Таким образом, каждый раз, когда приходит пакет, я должен взять его код операции и проверить его в файле конфигурации и вернуть соответствующий формат команды, представляющий формат этого пакета.

Формат командыможет выглядеть следующим образом:

код операции - 1 байт - целое число

команда - 4 байта - строка

...

Все команды неимеют одинаковое количество полей или одинаковый формат.

Я хочу получить все эти детали.Я могу представить его в XML и разобрать его с помощью некоторой библиотеки, например libxml2.

Ниже приведен пример XML-формата:

 <cmd type="Multiplication">
    <field name="opcode" type="string" bytes="4"/>
    <field name="Multiplicand" type="number" bytes="2"/>
    <field name="Multiplier" type="number" bytes="2"/>
 </cmd>

Но этот подход довольно медленный.

Я думаю как-то представить формат командного пакета в структурах.Но поскольку C / C ++ не является отражающим языком, члены структуры не могут быть известны, и вам потребуется одна функция на структуру (команду) для его анализа.

Пожалуйста, предложите какой-нибудь способ хранения форматов, чтобы один общийФункция может анализировать двоичные данные, просто взглянув на этот формат.

  • Языки могут быть C или C ++.
  • Производительность является главным приоритетом, поэтому XML и подобные типы не рекомендуется.
  • В памяти предпочтительны структуры данных.

Любая помощь высоко ценится.

1 Ответ

1 голос
/ 12 мая 2019

Я думаю, что вам лучше всего представить файл в виде набора variant с правильным типом команды. Например, допустим, у вас есть три варианта команд:

struct Constant {
    short value;
};
struct UnaryOperation {
    unsigned char opcode;
    short value;
};
struct BinaryOperation {
    unsigned char opcode;
    short value1;
    short value2;
};

Представление неизвестной команды. Если у вас есть неизвестная команда, вы можете представить ее как variant из трех типов:

using Command = std::variant<Constant, UnaryOperation, BinaryOperation>; 

Применение функции в зависимости от типа команды. Допустим, у вас есть разные функции для каждой команды:

short eval(Constant c) {
    return c.value;
}
short eval(UnaryOperation u) {
    switch(u.opcode) {
        // stuff
    }
}
short eval(BinaryOperation b) {
    switch(b.opcode) {
        // stuff
    }
}

Мы можем использовать std::visit для оценки произвольного Command:

short evaluate_command(Command const& command) {
    short output; 
    // This calls the right overload automatically 
    std::visit(command, [&](auto cmd) { output = eval(cmd); }); 
    return output; 
}

Парсинг команды. Мы можем создать std::variant автоматически из любого типа, для которого он определен. Это означает, что если вы предоставите способ выяснить, какая команда основана на файле, это довольно легко сделать.

enum class OpType : unsigned char {
    ConstantOp, UnaryOp, BinaryOp
};
// Command can be automatically constructed from a Constant, a UnaryOperation, or a BinaryOperation
Command readFromStream(std::istream& i) {
    OpType type;
    unsigned char op;
    short value, value2;

    // Read the type of the operation
    i >> (unsigned char&)type;

    //Return either a Constant, a UnaryOperation, or a BinaryOperation
    switch(type) {
        case OpType::ConstantOp: {
             i >> value;
             return Constant{value};
        }
        case OpType::UnaryOp: {
            i >> op >> value;
            return UnaryOperation{op, value};
        }
        case OpType::BinaryOp {
            i >> op >> value >> value2;
            return BinaryOperation{op, value, value2}; 
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...