Spec-Zone.ru › Elisp

Описание структуры данных

Чтобы управлять распаковкой и упаковкой, вы пишете спецификацию структуры данных, также называемую выражением типа Bindat. Это может быть базовый тип или составной тип, состоящий из нескольких полей; спецификация определяет длину обрабатываемого поля и способ его упаковки или распаковки. Значения типов Bindat обычно хранятся в переменных, имена которых оканчиваются на -bindat-spec; такие имена автоматически распознаются как потенциально опасные (см. Локальные переменные файла).

Макрос: bindat-type &rest type

Создаёт объект значения типа Bindat согласно выражению типа Bindat type.

Тип поля описывает размер (в байтах) представляемого этим полем объекта и, для многобайтовых полей, порядок следования байтов в поле. Возможны два порядка следования: от старшего байта к младшему (также известный как «сетевой порядок байтов») и от младшего байта к старшему. Например, число #x23cd (десятичное 9165) в порядке от старшего байта к младшему будет представлено двумя байтами #x23 #xcd, а в порядке от младшего байта к старшему — #xcd #x23. Ниже перечислены возможные значения типа:

u8
byte

Беззнаковый байт длиной 1.

uint bitlen &optional le

Беззнаковое целое число в сетевом порядке байтов (от старшего байта к младшему), длиной bitlen бит. Значение bitlen должно быть кратно 8. Если le не равно nil, используется порядок байтов от младшего к старшему.

sint bitlen le

Знаковое целое число в сетевом порядке байтов (от старшего байта к младшему), длиной bitlen бит. Значение bitlen должно быть кратно 8. Если le не равно nil, используется порядок байтов от младшего к старшему.

str len

Однобайтовая строка (см. Представления текста) длиной len байт. При упаковке первые len байт входной строки копируются в упакованные выходные данные. Если входная строка короче len, оставшиеся байты будут нулевыми (нулевыми байтами), если только в bindat-pack не была передана предварительно выделенная строка; в этом случае оставшиеся байты не изменяются. Если входная строка многобайтовая и содержит только символы ASCII и eight-bit, перед упаковкой она преобразуется в однобайтовую; для других многобайтовых строк возникает ошибка. При распаковке любые нулевые байты во входной упакованной строке появятся в распакованных выходных данных.

strz &optional len

Если len не задано, это строка переменной длины с нулевым байтом в качестве терминатора (см. Представления текста). При упаковке в strz вся входная строка копируется в упакованные выходные данные, после чего добавляется нулевой байт. (Если для упаковки в strz передана предварительно выделенная строка, в ней должно хватать места для дополнительного нулевого байта, добавляемого в конец содержимого выходной строки; см. Функции распаковки и упаковки байтов). Длина упакованных выходных данных равна длине входной строки плюс один (для завершающего нулевого байта). Входная строка не должна содержать нулевых байтов. Если входная строка многобайтовая и содержит только символы ASCII и eight-bit, перед упаковкой она преобразуется в однобайтовую; для других многобайтовых строк возникает ошибка. При распаковке strz результирующая выходная строка будет содержать все байты до нулевого байта, завершающего входную строку, но не включая его.

Если len задано, strz ведёт себя так же, как str, но с несколькими отличиями:

  • При упаковке после упакованной входной строки записывается нулевой байт, если количество символов во входной строке меньше len.
  • При распаковке первый обнаруженный в упакованной строке нулевой байт считается завершающим; он и все последующие байты исключаются из результата распаковки.

Внимание: Упакованные выходные данные не будут завершаться нулевым байтом, если только входная строка не короче len байт или не содержит нулевой байт среди первых len байт.

vec len [type]

Вектор из len элементов. Тип элементов задаётся значением type; по умолчанию используются байты. Значение type может быть любым выражением типа Bindat.

repeat len [type]

Аналогично vec, но распаковывает данные в списки и упаковывает их из списков, тогда как vec распаковывает данные в векторы.

bits len

Список битов, равных 1 в len байтах. Байты обрабатываются в порядке от старшего к младшему, а нумерация битов начинается с 8 * len − 1 и заканчивается нулём. Например: bits 2 распаковывает #x28 #x1c в (2 3 4 11 13), а #x1c #x28 — в (3 5 10 11 12).

fill len

len байт, используемых лишь в качестве заполнителя. При упаковке эти байты не изменяются; обычно это означает, что они остаются нулевыми. При распаковке возвращается nil.

align len

То же, что и fill, за исключением того, что количество байтов равно количеству, необходимому для перехода к следующему числу байтов, кратному len.

type exp

Позволяет ссылаться на тип косвенно: exp — это выражение Lisp, которое должно возвращать объект значения типа Bindat.

unit exp

Это тривиальный тип, занимающий 0 бит. exp описывает значение, возвращаемое при попытке «распаковать» такое поле.

struct fields...

Составной тип из нескольких полей. Каждое поле имеет вид (name type), где type может быть любым выражением типа Bindat. Вместо name можно указать _, если значение поля не заслуживает отдельного имени, как часто бывает для полей align и fill. Если из контекста ясно, что это выражение типа Bindat, символ struct можно опустить.

В приведённых выше типах len и bitlen задаются целым числом, указывающим количество байтов (или битов) в поле. Если длина поля не фиксирована, она обычно зависит от значения предшествующих полей. Поэтому длина len не обязательно должна быть константой: это может быть любое выражение Lisp, ссылающееся на значения предыдущих полей по их именам.

Например, спецификация структуры данных, в которой первый байт задаёт размер следующего за ним вектора 16-битных целых чисел, может выглядеть так:

(bindat-type
  (len      u8)
  (payload  vec (1+ len) uint 16))

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Bindat-Types.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API