Описание структуры данных
Чтобы управлять распаковкой и упаковкой, вы пишете спецификацию структуры данных, также называемую выражением типа Bindat. Это может быть базовый тип или составной тип, состоящий из нескольких полей; спецификация определяет длину обрабатываемого поля и способ его упаковки или распаковки. Значения типов Bindat обычно хранятся в переменных, имена которых оканчиваются на -bindat-spec; такие имена автоматически распознаются как потенциально опасные (см. Локальные переменные файла).
- Макрос: bindat-type &rest type
Создаёт объект значения типа Bindat согласно выражению типа Bindat type.
Тип поля описывает размер (в байтах) представляемого этим полем объекта и, для многобайтовых полей, порядок следования байтов в поле. Возможны два порядка следования: от старшего байта к младшему (также известный как «сетевой порядок байтов») и от младшего байта к старшему. Например, число #x23cd (десятичное 9165) в порядке от старшего байта к младшему будет представлено двумя байтами #x23 #xcd, а в порядке от младшего байта к старшему — #xcd #x23. Ниже перечислены возможные значения типа:
u8byte-
Беззнаковый байт длиной 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