Хотя Perl ориентирован в первую очередь на обработку текста,он также может обрабатывать бинарные данные. Скрипты могут перемещать бинарные данные частями, используя строковые переменные, ивыполнять байтовые операции ввода/вывода, используя функцииsysread и syswrite. Однако для того, чтобы выполнить что-нибудь <полезное> с данными, скрипт вынужден конвертировать данные всвои <родные> скалярные форматы.
Хранение бинарных данных
Когда скрипт на языке Perl читает блок бинарных данных, используя функцию sysread, он помещает эти бинарные данные в скалярную строковую переменную. Perl не заботится о том, что это заданные, содержат ли они нули или значения, не являющиеся АSCII-символами. В пределах символьной строки Perl принимает байты как байты. В отличие от языка С, Perl не использует строк, оканчивающихся нуль-символом. Если данные соответствуют кодовой таблице ASCII, то скрипт может их обрабатывать, как любой текст. Но если данные представляют собой бинарные величины, то скрипт обязан распаковать их перед тем, как Perl сможет обработать эти данные.
Распаковка строк бинарных данных в переменные языка PERL
Для того чтобы скрипт получил доступ к бинарным данным, он должен распаковать их, перейдя в свой скалярный формат. Скрипты Perl распаковывают данные, используя функцию unpack, которая имеет следующий формат:
$result = unpack(Template, Expression);
Expression является обычной строковой переменной, которая содержит бинарные данные, прочитанные функцией sysread, но может быть также выражением, которое необходимо интерпретировать как строку. Template представляет собой символьную строку-шаблон, описывающую, как интерпретировать значения в операнде Expression. Следующий фрагмент программы иллюстрирует использование функции unpack:
($r, $g, $b) = unpack("C3", $color);# распакует в 3 символа @longwords = unpack("L*", $data); # распакует в список длинных # слов @stuff = unpack("S2L", $bin); # распакует в 2 shorts и long
Каждый символ шаблона может сопровождаться числом, указывающим, сколько раз использовать этот символ. Если вместо числа стоит звездочка (*), то операция будет выполняться для всех остающихся данных в строке. Если число не поставлено, то она выполняется однократно. Скрипт может поместить любое число символов шаблона в строку Template. В таблице перечисляются символы, входящие в строковый параметр Template вместе с описанием влияния каждого из них на выполнение функции unpack.
Символ шаблона | Описание | a | Строка ASCII без нулевого символа | А | Строка ASCII без нулевого символа | b | Битовая строка (младший бит идет первым) | В | Битовая строка (старший бит идет первым) | с | Однобайтовый символ со знаком | С | Однобайтовый символ без знака | d | Значение с плавающей запятой, двойной точности | f | Значение с плавающей запятой, одинарной точности шаблона | h | Строка шестнадцатиричных значений (младшие разряды идут первыми) | Н | Строка шестнадцатиричных значений (старшие разряды идут первыми) | i | Целое со знаком | I | Целое без знака | l | Целое со знаком типа long | L | То же, только без знака | n | Короткое целое | N | Длинное целое | p | Указатель на строку | s | Короткое целое со знаком | S | Короткое целое без знака | u | Раскодировка строки | v | Короткое целое | V | Длинное целое | x | Пропустить вперед один байт | X | Пропустить назад один байт | @ | Перейти на указанную позицию в строке |
Упаковка данных в бинарные строки
Для вывода бинарных данных скрипт должен запаковать скалярные величины в строки бинарных символов. Для этого используется функция pack, формат которой указан ниже:
$result = pack(Template, List);
Следующий фрагмент программы иллюстрирует использование функции pack:
$color = pack("C3", $r, $g, $b); $data = pack("L*", @longword); $bin = pack("S2L", @stuff);
Функция pack использует те же самые символы шаблона, что ифункция unpack, за исключением символов а. А, и, х, X, @.
8 8 8
| |