Упаковка данных [Lua 5.3]

Упаковка данных [Lua 5.3]

При имплементации интернет-протоколов часто требуется упаковать значения в определённом формате. Например, представить число 0x123456 в виде 32-битного целого числа в формате Big-endian (и получить строку "\0\x12\x34\x56").

Для этих целей Lua 5.3 имеет функции string.pack, string.unpack и string.packsize. Все они требуют строку формата.

Строка формата — это последовательный набор символов, которые определяют, как будут конвертироваться значения.

Опция Тип аргумента Описание
Конфигурация
< Устанавливает формат little-endian для последующих опций.
> Устанавливает формат big-endian для последующих опций.
= Устанавливает формат LE/BE в зависимости от платформы, на которой исполняется код, для последующих опций
!n Устанавливает выравнивание на i байт.
Аргументы
b Целое число Знаковый числовой тип char (1 байт)
B Целое число Беззнаковый числовой тип char (1 байт)
h Целое число Знаковый числовой тип short
H Целое число Беззнаковый числовой тип short
l Целое число Знаковый числовой тип long
L Целое число Беззнаковый числовой тип long
j Целое число Числовой тип lua_Integer
J Целое число Числовой тип lua_Unsigned
T Целое число Числовой тип size_t
i Целое число Знаковый числовой тип int
I Целое число Беззнаковый числовой тип int
in Целое число Число размером в n байт со знаком
In Целое число Число размером в n байт без знака
f Число Число типа float
d Число Число типа double
n Число Число типа lua_Number
cn Строка Строка размером в n байт
z Строка Строка, заканчивающаяся нулевым байтом \0
s Строка Строка, перед которой записан её размер числом типа size_t
sn Строка Строка, перед которой записан её размер числом размером в n байт
Пэддинг
x Один байт пэддинга (нулевой байт)

Пробелы в строке формата игнорируются.

Скармливать её можно в три функции:

  • string.pack(formatString: string, args...) — спакует значения в строку по формату.
  • string.unpack(formatString: string, args...) — распакует значения из строки по формату.
  • string.packsize(formatString: string) — вернёт размер строки, получаемой из string.pack с данной строкой формата. Последняя не должна содержать опции s или z.

Примеры

-- Для удобства определим функцию `hex`.
local function hex(s)
  return s:gsub(".", function(c)
    return ("%02x "):format(c:byte())
  end):sub(1, -2)
end

print(hex(string.pack("> s3 I4 n", "hello", 0x12345678, math.pi)))
--> 00 00 05 68 65 6c 6c 6f 12 34 56 78 40 09 21 fb 54 44 2d 18
--[[\______/ \____________/ \_________/ \_____________________/
     длина   строка "hello"      I4      число 3.1415926535898
    \_____________________/                    lua_Number
              s3
  ]]

print(string.unpack(
  "> s3 I4 n",
  "\0\0\5\x68\x65\x6c\x6c\x6f\x12\x34\x56\x78\x40\9\x21\xfb\x54\x44\x2d\x18"
))
--> hello   305419896       3.1415926535898

-- (на разных машинах может отличаться)
print(string.packsize("> I4 n f T"))
--> 24

Подробнее

results for ""

    No results matching ""