LINUX.ORG.RU

Знатокам Perl. Распаковка данных.


0

0

Здравствуйте, уважаемые!

Кто подскажет, как бы так по «красивше» решить задачу распаковки последовательности двоичных данных в формате: [LEN1][DATA1][LEN2][DATA2][...]?

Пока использую такую конструкцию (режет глаза, однако):

while ($data) {
    my $block_size = unpack("L", $data);
    my $block_data = unpack("x4c$block_size", $data);

    ....

    $data = substr($data, $block_size + 4);
}
Заранее благодарен!

★★

Ну если я правильно понял задачу, то решение тривиально - использовать слеш («/»). Привожу пример:

#!/usr/bin/perl
use strict;
# данные
my @words = qw(hello qwe  world);
# упаковываем данные, вписывая длину перед каждым блоком данных
my $packed_data = pack('(S/A*)*', @words);

# распаковываем данные, автоматически вычитавая длину блока перед данными
my @new_words = unpack('(S/A*)*', $packed_data);
print join ', ', @new_words

Должно печатать hello, qwe, world.

d_a ★★★★★
()
Ответ на: комментарий от d_a

Благодарю! Похоже то, что нужно. Только у меня длина - 4 байта (L), и строки двоичные (C).

Сам я что-то не смог с pack/unpack разобраться - про "/" читал, пытался использовать, но дальше, чем преобразование одной записи так и продвинулся. Не могли бы вы пояснить как работает такой шаблон?

i82 ★★
() автор топика
Ответ на: комментарий от i82

Я могу рассказать, как я это понял, а не как он работает, так что вряд ли объяснение сможет претендовать на полноту и ясность :)

В случае с pack'ом, запись S/A* (или L/C*) означает взять длину переданного в pack сразу после шаблона скаляра, запаковать ее как S (или L), взять сам скаляр, запаковать его как A (или C), и вернуть скаляр, конкатенированный из первого и второго результатов. Группировка с повторением шаблона «до победного» (конструкция (...)*) позволяет пройтись по всем переданным данным (в примере - по всему массиву @words).

Unpack тоже здесь работает довольно прозрачно - распаковывает значение длины блока (как S или L) и затем распаковывает ровно столько байтов, сколько было таким образом «вычитано». Ну и опять же группировка с повторением позволяет пройтись по всему упакованному «буферу» и вернуть в резальтате своей работы тот самый массив (data1, data2, ... ,dataN).

d_a ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.