Разбор последовательности байт.
Код:
00 00 00 2F 00 00 00 02 00 00 00 00 00 00 00 01 53 4D 50 50 33 54 45 53 54 00 73 65 63 72 65 74 30 38 00 53 55 42 4D 49 54 31 00 00 01 01 00
Это пример, бывают и другие виды последовательностей. В этой последовательности закодированы данные нескольких разных типов:
Цитата:
Integer An unsigned value with the defined number of octets.
The octets will always be transmitted MSB first (Big Endian).
C-Octet String A series of ASCII characters terminated with the NULL character.
C-Octet String
(Decimal)
A series of ASCII characters, each character representing a
decimal digit (0 - 9) and terminated with the NULL character.
C-Octet String
(Hex)
A series of ASCII characters, each character representing a
hexadecimal digit (0 - F) and terminated with the NULL character.
Octet String A series of octets, not necessarily NULL terminated.
The octets will always be transmitted MSB first (Big Endian).
C-Octet String A series of ASCII characters terminated with the NULL character.
C-Octet String
(Decimal)
A series of ASCII characters, each character representing a
decimal digit (0 - 9) and terminated with the NULL character.
C-Octet String
(Hex)
A series of ASCII characters, each character representing a
hexadecimal digit (0 - F) and terminated with the NULL character.
Octet String A series of octets, not necessarily NULL terminated.
В общем случае последовательность расшифровывается так: первые 16 байт - заголовок, всё остальное - данные. По заголовку можно определить, какие именно данные приходят; то есть, в какой последовательности идут поля того или иного типа.
Задача: разобрать последовательность байт в структуру, или, лучше, в экземпляр класса.
Несколько лет тому назад я уже решал эту задачу; решение было тупое и китайское, но оно и поныне работает. :) Идея заключалась в том, что всего имеется штук десять разновидностей пакетов, которые мы можем принять по условию задачи. Для каждой разновидности был написан парсер, который в определённой последовательности разбирал поля данных от заголовка до конца пакета. Примерно так:
Код:
read_int();
read_varstring();
read_varstring();
read_string();
read_int();
read_varstring();
read_varstring();
read_string();
read_int();
То есть, если пакет состоит из четырёх целых, потом двух строк с нулём и одной без нуля, то так и читал - сначала целые, потом строки с нулём и т.д. Решение это работающее, но какое-то уж очень китайское. Отсюда вопрос: есть ли какой-то более красивый способ прочитать данные из набора байт?
P.S. По условию задачи нужно реализовать и обратное преобразование, но оно выполняется легко и просто.
конкретизируй, какова цель предполагаемого улучшения или каким оразом используются данные полученные в результате парсинга, тогда можно будет сформулировать более конкретные предложения.
Интерес к улучшению скорее академический, поскольку как сделать просто работающее решение - я знаю; интересно скорее узнать, можно ли как-то улучшить это. Просто когда я писал это решение впервые, я не бог весть как хорошо знал рабочий инструмент, а о написании разборщиков не знал вообще ничего. Тем не менее, путь оказался вполне верный. Пожалуй, тогда стоит просто улучшить некоторые детали реализации, которые тогда были сделаны очень уж колхозно.
По-моему, проще будет написать по функции на каждый уникальный тип последовательности, а потом вызывать их в зависимости от заголовка. Хотя можно и универсальный парсер инициализировать, будет расширяемо. Надо посмотреть, что проще будет.
вобще-то из приведенного описания не сильно понятно чем плох данный подход и в какую сторону его следует улучшать... если только написать универсальный парсер, который будет инициализироваться строкой типа "IVVS" (int-varstring-varstring-string) и отображать разные варианты заголовка на экземпляры этого парсера.